summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/audio/audio_driver_dummy.cpp4
-rw-r--r--servers/audio/audio_driver_dummy.h4
-rw-r--r--servers/audio/audio_effect.cpp4
-rw-r--r--servers/audio/audio_effect.h4
-rw-r--r--servers/audio/audio_filter_sw.cpp4
-rw-r--r--servers/audio/audio_filter_sw.h4
-rw-r--r--servers/audio/audio_rb_resampler.cpp6
-rw-r--r--servers/audio/audio_rb_resampler.h4
-rw-r--r--servers/audio/audio_stream.cpp4
-rw-r--r--servers/audio/audio_stream.h4
-rw-r--r--servers/audio/effects/audio_effect_amplify.cpp4
-rw-r--r--servers/audio/effects/audio_effect_amplify.h4
-rw-r--r--servers/audio/effects/audio_effect_capture.cpp4
-rw-r--r--servers/audio/effects/audio_effect_capture.h4
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp4
-rw-r--r--servers/audio/effects/audio_effect_chorus.h4
-rw-r--r--servers/audio/effects/audio_effect_compressor.cpp4
-rw-r--r--servers/audio/effects/audio_effect_compressor.h4
-rw-r--r--servers/audio/effects/audio_effect_delay.cpp4
-rw-r--r--servers/audio/effects/audio_effect_delay.h4
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp4
-rw-r--r--servers/audio/effects/audio_effect_distortion.h4
-rw-r--r--servers/audio/effects/audio_effect_eq.cpp4
-rw-r--r--servers/audio/effects/audio_effect_eq.h4
-rw-r--r--servers/audio/effects/audio_effect_filter.cpp4
-rw-r--r--servers/audio/effects/audio_effect_filter.h4
-rw-r--r--servers/audio/effects/audio_effect_limiter.cpp4
-rw-r--r--servers/audio/effects/audio_effect_limiter.h4
-rw-r--r--servers/audio/effects/audio_effect_panner.cpp4
-rw-r--r--servers/audio/effects/audio_effect_panner.h4
-rw-r--r--servers/audio/effects/audio_effect_phaser.cpp4
-rw-r--r--servers/audio/effects/audio_effect_phaser.h4
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp4
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.h4
-rw-r--r--servers/audio/effects/audio_effect_record.cpp4
-rw-r--r--servers/audio/effects/audio_effect_record.h4
-rw-r--r--servers/audio/effects/audio_effect_reverb.cpp4
-rw-r--r--servers/audio/effects/audio_effect_reverb.h4
-rw-r--r--servers/audio/effects/audio_effect_spectrum_analyzer.cpp4
-rw-r--r--servers/audio/effects/audio_effect_spectrum_analyzer.h4
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.cpp4
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.h4
-rw-r--r--servers/audio/effects/audio_stream_generator.cpp4
-rw-r--r--servers/audio/effects/audio_stream_generator.h4
-rw-r--r--servers/audio/effects/eq.cpp4
-rw-r--r--servers/audio/effects/eq.h4
-rw-r--r--servers/audio/effects/reverb.cpp4
-rw-r--r--servers/audio/effects/reverb.h4
-rw-r--r--servers/audio_server.cpp6
-rw-r--r--servers/audio_server.h4
-rw-r--r--servers/camera/camera_feed.cpp4
-rw-r--r--servers/camera/camera_feed.h4
-rw-r--r--servers/camera_server.cpp4
-rw-r--r--servers/camera_server.h4
-rw-r--r--servers/display_server.cpp4
-rw-r--r--servers/display_server.h4
-rw-r--r--servers/display_server_headless.h4
-rw-r--r--servers/navigation_server_2d.cpp4
-rw-r--r--servers/navigation_server_2d.h4
-rw-r--r--servers/navigation_server_3d.cpp4
-rw-r--r--servers/navigation_server_3d.h4
-rw-r--r--servers/physics_2d/godot_area_2d.cpp4
-rw-r--r--servers/physics_2d/godot_area_2d.h4
-rw-r--r--servers/physics_2d/godot_area_pair_2d.cpp4
-rw-r--r--servers/physics_2d/godot_area_pair_2d.h4
-rw-r--r--servers/physics_2d/godot_body_2d.cpp14
-rw-r--r--servers/physics_2d/godot_body_2d.h68
-rw-r--r--servers/physics_2d/godot_body_direct_state_2d.cpp65
-rw-r--r--servers/physics_2d/godot_body_direct_state_2d.h21
-rw-r--r--servers/physics_2d/godot_body_pair_2d.cpp213
-rw-r--r--servers/physics_2d/godot_body_pair_2d.h10
-rw-r--r--servers/physics_2d/godot_broad_phase_2d.cpp4
-rw-r--r--servers/physics_2d/godot_broad_phase_2d.h4
-rw-r--r--servers/physics_2d/godot_broad_phase_2d_bvh.cpp4
-rw-r--r--servers/physics_2d/godot_broad_phase_2d_bvh.h4
-rw-r--r--servers/physics_2d/godot_collision_object_2d.cpp4
-rw-r--r--servers/physics_2d/godot_collision_object_2d.h4
-rw-r--r--servers/physics_2d/godot_collision_solver_2d.cpp4
-rw-r--r--servers/physics_2d/godot_collision_solver_2d.h4
-rw-r--r--servers/physics_2d/godot_collision_solver_2d_sat.cpp4
-rw-r--r--servers/physics_2d/godot_collision_solver_2d_sat.h4
-rw-r--r--servers/physics_2d/godot_constraint_2d.h4
-rw-r--r--servers/physics_2d/godot_joints_2d.cpp4
-rw-r--r--servers/physics_2d/godot_joints_2d.h4
-rw-r--r--servers/physics_2d/godot_physics_server_2d.cpp147
-rw-r--r--servers/physics_2d/godot_physics_server_2d.h32
-rw-r--r--servers/physics_2d/godot_shape_2d.cpp4
-rw-r--r--servers/physics_2d/godot_shape_2d.h4
-rw-r--r--servers/physics_2d/godot_space_2d.cpp60
-rw-r--r--servers/physics_2d/godot_space_2d.h19
-rw-r--r--servers/physics_2d/godot_step_2d.cpp8
-rw-r--r--servers/physics_2d/godot_step_2d.h6
-rw-r--r--servers/physics_3d/gjk_epa.cpp4
-rw-r--r--servers/physics_3d/gjk_epa.h4
-rw-r--r--servers/physics_3d/godot_area_3d.cpp4
-rw-r--r--servers/physics_3d/godot_area_3d.h4
-rw-r--r--servers/physics_3d/godot_area_pair_3d.cpp4
-rw-r--r--servers/physics_3d/godot_area_pair_3d.h4
-rw-r--r--servers/physics_3d/godot_body_3d.cpp9
-rw-r--r--servers/physics_3d/godot_body_3d.h38
-rw-r--r--servers/physics_3d/godot_body_direct_state_3d.cpp65
-rw-r--r--servers/physics_3d/godot_body_direct_state_3d.h21
-rw-r--r--servers/physics_3d/godot_body_pair_3d.cpp180
-rw-r--r--servers/physics_3d/godot_body_pair_3d.h6
-rw-r--r--servers/physics_3d/godot_broad_phase_3d.cpp4
-rw-r--r--servers/physics_3d/godot_broad_phase_3d.h4
-rw-r--r--servers/physics_3d/godot_broad_phase_3d_bvh.cpp4
-rw-r--r--servers/physics_3d/godot_broad_phase_3d_bvh.h4
-rw-r--r--servers/physics_3d/godot_collision_object_3d.cpp4
-rw-r--r--servers/physics_3d/godot_collision_object_3d.h4
-rw-r--r--servers/physics_3d/godot_collision_solver_3d.cpp4
-rw-r--r--servers/physics_3d/godot_collision_solver_3d.h4
-rw-r--r--servers/physics_3d/godot_collision_solver_3d_sat.cpp4
-rw-r--r--servers/physics_3d/godot_collision_solver_3d_sat.h4
-rw-r--r--servers/physics_3d/godot_constraint_3d.h4
-rw-r--r--servers/physics_3d/godot_joint_3d.h4
-rw-r--r--servers/physics_3d/godot_physics_server_3d.cpp141
-rw-r--r--servers/physics_3d/godot_physics_server_3d.h32
-rw-r--r--servers/physics_3d/godot_shape_3d.cpp4
-rw-r--r--servers/physics_3d/godot_shape_3d.h4
-rw-r--r--servers/physics_3d/godot_soft_body_3d.cpp4
-rw-r--r--servers/physics_3d/godot_soft_body_3d.h4
-rw-r--r--servers/physics_3d/godot_space_3d.cpp61
-rw-r--r--servers/physics_3d/godot_space_3d.h29
-rw-r--r--servers/physics_3d/godot_step_3d.cpp8
-rw-r--r--servers/physics_3d/godot_step_3d.h6
-rw-r--r--servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp4
-rw-r--r--servers/physics_3d/joints/godot_cone_twist_joint_3d.h4
-rw-r--r--servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp4
-rw-r--r--servers/physics_3d/joints/godot_generic_6dof_joint_3d.h4
-rw-r--r--servers/physics_3d/joints/godot_hinge_joint_3d.cpp4
-rw-r--r--servers/physics_3d/joints/godot_hinge_joint_3d.h4
-rw-r--r--servers/physics_3d/joints/godot_jacobian_entry_3d.h4
-rw-r--r--servers/physics_3d/joints/godot_pin_joint_3d.cpp4
-rw-r--r--servers/physics_3d/joints/godot_pin_joint_3d.h4
-rw-r--r--servers/physics_3d/joints/godot_slider_joint_3d.cpp4
-rw-r--r--servers/physics_3d/joints/godot_slider_joint_3d.h4
-rw-r--r--servers/physics_server_2d.cpp45
-rw-r--r--servers/physics_server_2d.h56
-rw-r--r--servers/physics_server_2d_wrap_mt.cpp4
-rw-r--r--servers/physics_server_2d_wrap_mt.h29
-rw-r--r--servers/physics_server_3d.cpp48
-rw-r--r--servers/physics_server_3d.h58
-rw-r--r--servers/physics_server_3d_wrap_mt.cpp4
-rw-r--r--servers/physics_server_3d_wrap_mt.h29
-rw-r--r--servers/register_server_types.cpp4
-rw-r--r--servers/register_server_types.h4
-rw-r--r--servers/rendering/rasterizer_dummy.h10
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp6
-rw-r--r--servers/rendering/renderer_canvas_cull.h4
-rw-r--r--servers/rendering/renderer_canvas_render.cpp4
-rw-r--r--servers/rendering/renderer_canvas_render.h4
-rw-r--r--servers/rendering/renderer_compositor.cpp4
-rw-r--r--servers/rendering/renderer_compositor.h4
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.h4
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp776
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h199
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp38
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h6
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp6
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp6
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp6
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h4
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/pipeline_cache_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp8
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_environment_rd.h12
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp21
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.h22
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp413
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h72
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp14
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp28
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h4
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.cpp96
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.h4
-rw-r--r--servers/rendering/renderer_rd/shader_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/shader_rd.h4
-rw-r--r--servers/rendering/renderer_rd/shaders/copy.glsl16
-rw-r--r--servers/rendering/renderer_rd/shaders/fsr_upscale.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/gi.glsl18
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_write.glsl1
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl8
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl25
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl1
-rw-r--r--servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl (renamed from servers/rendering/renderer_rd/shaders/ssao_downsample.glsl)23
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao.glsl3
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_blur.glsl14
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl7
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil.glsl444
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_blur.glsl124
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl124
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_interleave.glsl102
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl43
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi.glsl1
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl56
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl5
-rw-r--r--servers/rendering/renderer_scene.cpp4
-rw-r--r--servers/rendering/renderer_scene.h8
-rw-r--r--servers/rendering/renderer_scene_cull.cpp4
-rw-r--r--servers/rendering/renderer_scene_cull.h7
-rw-r--r--servers/rendering/renderer_scene_occlusion_cull.cpp4
-rw-r--r--servers/rendering/renderer_scene_occlusion_cull.h4
-rw-r--r--servers/rendering/renderer_scene_render.cpp4
-rw-r--r--servers/rendering/renderer_scene_render.h8
-rw-r--r--servers/rendering/renderer_storage.cpp4
-rw-r--r--servers/rendering/renderer_storage.h4
-rw-r--r--servers/rendering/renderer_thread_pool.cpp4
-rw-r--r--servers/rendering/renderer_thread_pool.h4
-rw-r--r--servers/rendering/renderer_viewport.cpp4
-rw-r--r--servers/rendering/renderer_viewport.h4
-rw-r--r--servers/rendering/rendering_device.cpp24
-rw-r--r--servers/rendering/rendering_device.h8
-rw-r--r--servers/rendering/rendering_device_binds.cpp20
-rw-r--r--servers/rendering/rendering_device_binds.h8
-rw-r--r--servers/rendering/rendering_server_default.cpp4
-rw-r--r--servers/rendering/rendering_server_default.h7
-rw-r--r--servers/rendering/rendering_server_globals.cpp4
-rw-r--r--servers/rendering/rendering_server_globals.h4
-rw-r--r--servers/rendering/shader_language.cpp1010
-rw-r--r--servers/rendering/shader_language.h121
-rw-r--r--servers/rendering/shader_types.cpp146
-rw-r--r--servers/rendering/shader_types.h8
-rw-r--r--servers/rendering/shader_warnings.cpp20
-rw-r--r--servers/rendering/shader_warnings.h13
-rw-r--r--servers/rendering_server.cpp81
-rw-r--r--servers/rendering_server.h74
-rw-r--r--servers/server_wrap_mt_common.h4
-rw-r--r--servers/text/text_server_extension.cpp8
-rw-r--r--servers/text/text_server_extension.h12
-rw-r--r--servers/text_server.cpp22
-rw-r--r--servers/text_server.h10
-rw-r--r--servers/xr/xr_interface.cpp4
-rw-r--r--servers/xr/xr_interface.h4
-rw-r--r--servers/xr/xr_interface_extension.cpp4
-rw-r--r--servers/xr/xr_interface_extension.h4
-rw-r--r--servers/xr/xr_pose.cpp4
-rw-r--r--servers/xr/xr_pose.h4
-rw-r--r--servers/xr/xr_positional_tracker.cpp4
-rw-r--r--servers/xr/xr_positional_tracker.h4
-rw-r--r--servers/xr_server.cpp4
-rw-r--r--servers/xr_server.h4
250 files changed, 4499 insertions, 2062 deletions
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index 47799dce96..1ba0afd8a1 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h
index 7d84e7ffc8..6324e2f5d3 100644
--- a/servers/audio/audio_driver_dummy.h
+++ b/servers/audio/audio_driver_dummy.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp
index 3035828c95..b9eca14a4c 100644
--- a/servers/audio/audio_effect.cpp
+++ b/servers/audio/audio_effect.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h
index bea7292b8e..00a5d6c004 100644
--- a/servers/audio/audio_effect.h
+++ b/servers/audio/audio_effect.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp
index b31014bd21..082931647a 100644
--- a/servers/audio/audio_filter_sw.cpp
+++ b/servers/audio/audio_filter_sw.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h
index 540d6368e3..9e55662d0a 100644
--- a/servers/audio/audio_filter_sw.h
+++ b/servers/audio/audio_filter_sw.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index d9c442facf..0cfba17563 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -43,7 +43,7 @@ int AudioRBResampler::get_channel_count() const {
// Linear interpolation based sample rate conversion (low quality)
// Note that AudioStreamPlaybackResampled::mix has better algorithm,
-// but it wasn't obvious to integrate that with VideoPlayer
+// but it wasn't obvious to integrate that with VideoStreamPlayer
template <int C>
uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) {
uint32_t read = offset & MIX_FRAC_MASK;
diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h
index c0f981704b..3fbe684c3e 100644
--- a/servers/audio/audio_rb_resampler.h
+++ b/servers/audio/audio_rb_resampler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index c098a97906..170a7ef967 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 12d4343f5c..32159e96ef 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_amplify.cpp b/servers/audio/effects/audio_effect_amplify.cpp
index 79788d334b..b01160ea5c 100644
--- a/servers/audio/effects/audio_effect_amplify.cpp
+++ b/servers/audio/effects/audio_effect_amplify.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_amplify.h b/servers/audio/effects/audio_effect_amplify.h
index 9d3facc230..bd0fcaa94d 100644
--- a/servers/audio/effects/audio_effect_amplify.h
+++ b/servers/audio/effects/audio_effect_amplify.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp
index 065065042e..f605cfc9d4 100644
--- a/servers/audio/effects/audio_effect_capture.cpp
+++ b/servers/audio/effects/audio_effect_capture.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_capture.h b/servers/audio/effects/audio_effect_capture.h
index bb1d03be8c..3935f7d473 100644
--- a/servers/audio/effects/audio_effect_capture.h
+++ b/servers/audio/effects/audio_effect_capture.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp
index 9af3ed30cc..8b1fe9cfd2 100644
--- a/servers/audio/effects/audio_effect_chorus.cpp
+++ b/servers/audio/effects/audio_effect_chorus.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_chorus.h b/servers/audio/effects/audio_effect_chorus.h
index f81bebb0ae..19035222c5 100644
--- a/servers/audio/effects/audio_effect_chorus.h
+++ b/servers/audio/effects/audio_effect_chorus.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp
index cfa2ae6f79..f75d092dd3 100644
--- a/servers/audio/effects/audio_effect_compressor.cpp
+++ b/servers/audio/effects/audio_effect_compressor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_compressor.h b/servers/audio/effects/audio_effect_compressor.h
index dae4618a64..53c448e5db 100644
--- a/servers/audio/effects/audio_effect_compressor.h
+++ b/servers/audio/effects/audio_effect_compressor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp
index 07475e1ed4..bddd235204 100644
--- a/servers/audio/effects/audio_effect_delay.cpp
+++ b/servers/audio/effects/audio_effect_delay.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_delay.h b/servers/audio/effects/audio_effect_delay.h
index 50a2233e5f..5cc6d72c99 100644
--- a/servers/audio/effects/audio_effect_delay.h
+++ b/servers/audio/effects/audio_effect_delay.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp
index 188b7a3301..afc4353bd7 100644
--- a/servers/audio/effects/audio_effect_distortion.cpp
+++ b/servers/audio/effects/audio_effect_distortion.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_distortion.h b/servers/audio/effects/audio_effect_distortion.h
index 3a762f8cf6..487babbdda 100644
--- a/servers/audio/effects/audio_effect_distortion.h
+++ b/servers/audio/effects/audio_effect_distortion.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_eq.cpp b/servers/audio/effects/audio_effect_eq.cpp
index e87944b74b..cc317031d4 100644
--- a/servers/audio/effects/audio_effect_eq.cpp
+++ b/servers/audio/effects/audio_effect_eq.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_eq.h b/servers/audio/effects/audio_effect_eq.h
index b99727d7c0..252f931e6c 100644
--- a/servers/audio/effects/audio_effect_eq.h
+++ b/servers/audio/effects/audio_effect_eq.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_filter.cpp b/servers/audio/effects/audio_effect_filter.cpp
index 1db8b1f1b5..06e66f22b1 100644
--- a/servers/audio/effects/audio_effect_filter.cpp
+++ b/servers/audio/effects/audio_effect_filter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_filter.h b/servers/audio/effects/audio_effect_filter.h
index 1fa3df1570..d5d58ddaa3 100644
--- a/servers/audio/effects/audio_effect_filter.h
+++ b/servers/audio/effects/audio_effect_filter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_limiter.cpp b/servers/audio/effects/audio_effect_limiter.cpp
index 280411641b..5923cf8cf5 100644
--- a/servers/audio/effects/audio_effect_limiter.cpp
+++ b/servers/audio/effects/audio_effect_limiter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_limiter.h b/servers/audio/effects/audio_effect_limiter.h
index 398613aa44..f84a0ae103 100644
--- a/servers/audio/effects/audio_effect_limiter.h
+++ b/servers/audio/effects/audio_effect_limiter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_panner.cpp b/servers/audio/effects/audio_effect_panner.cpp
index e2062609b9..278acda86c 100644
--- a/servers/audio/effects/audio_effect_panner.cpp
+++ b/servers/audio/effects/audio_effect_panner.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_panner.h b/servers/audio/effects/audio_effect_panner.h
index d75bcaeb95..d05c9902af 100644
--- a/servers/audio/effects/audio_effect_panner.h
+++ b/servers/audio/effects/audio_effect_panner.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp
index c76692eed7..af5dce707e 100644
--- a/servers/audio/effects/audio_effect_phaser.cpp
+++ b/servers/audio/effects/audio_effect_phaser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_phaser.h b/servers/audio/effects/audio_effect_phaser.h
index 2a0ed64805..80b7742835 100644
--- a/servers/audio/effects/audio_effect_phaser.h
+++ b/servers/audio/effects/audio_effect_phaser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index d6c396e0a5..3c53887931 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h
index 3ed096cd94..0478d05ceb 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.h
+++ b/servers/audio/effects/audio_effect_pitch_shift.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index f71679d30f..569832b8a8 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h
index 6e862b1377..18b5d4d83c 100644
--- a/servers/audio/effects/audio_effect_record.h
+++ b/servers/audio/effects/audio_effect_record.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_reverb.cpp b/servers/audio/effects/audio_effect_reverb.cpp
index 819f906773..0d4eb14e6a 100644
--- a/servers/audio/effects/audio_effect_reverb.cpp
+++ b/servers/audio/effects/audio_effect_reverb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_reverb.h b/servers/audio/effects/audio_effect_reverb.h
index eaa66352f6..90694c5492 100644
--- a/servers/audio/effects/audio_effect_reverb.h
+++ b/servers/audio/effects/audio_effect_reverb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
index 6f9e7ac67d..10627be74c 100644
--- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
+++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.h b/servers/audio/effects/audio_effect_spectrum_analyzer.h
index 3c5ae4a5e8..982c20d4a4 100644
--- a/servers/audio/effects/audio_effect_spectrum_analyzer.h
+++ b/servers/audio/effects/audio_effect_spectrum_analyzer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp
index 3a016b06b8..757edd6d43 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.cpp
+++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.h b/servers/audio/effects/audio_effect_stereo_enhance.h
index e0f9d79a94..8b8b7b47a0 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.h
+++ b/servers/audio/effects/audio_effect_stereo_enhance.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp
index 447acf53a4..6c917f3eb6 100644
--- a/servers/audio/effects/audio_stream_generator.cpp
+++ b/servers/audio/effects/audio_stream_generator.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/audio_stream_generator.h b/servers/audio/effects/audio_stream_generator.h
index 918589f6d0..51288262b3 100644
--- a/servers/audio/effects/audio_stream_generator.h
+++ b/servers/audio/effects/audio_stream_generator.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp
index e0c3eb6d3a..2123284b3b 100644
--- a/servers/audio/effects/eq.cpp
+++ b/servers/audio/effects/eq.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h
index afd5bf5334..74280ee22e 100644
--- a/servers/audio/effects/eq.h
+++ b/servers/audio/effects/eq.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp
index 1d97de5205..4b5b9ab79f 100644
--- a/servers/audio/effects/reverb.cpp
+++ b/servers/audio/effects/reverb.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h
index e7ce55098d..fa06d262a3 100644
--- a/servers/audio/effects/reverb.h
+++ b/servers/audio/effects/reverb.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index f7c8f0921c..c89f811678 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1591,7 +1591,7 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
Bus::Effect bfx;
bfx.effect = fx;
bfx.enabled = p_bus_layout->buses[i].effects[j].enabled;
-#if DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
bfx.prof_time = 0;
#endif
bus->effects.push_back(bfx);
diff --git a/servers/audio_server.h b/servers/audio_server.h
index 46873845dc..0c150427f2 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/camera/camera_feed.cpp b/servers/camera/camera_feed.cpp
index 9f8e8a8106..3aab995857 100644
--- a/servers/camera/camera_feed.cpp
+++ b/servers/camera/camera_feed.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/camera/camera_feed.h b/servers/camera/camera_feed.h
index 1f80d15e30..ea66c5f947 100644
--- a/servers/camera/camera_feed.h
+++ b/servers/camera/camera_feed.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/camera_server.cpp b/servers/camera_server.cpp
index 8391a2ee2e..91df3afadd 100644
--- a/servers/camera_server.cpp
+++ b/servers/camera_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/camera_server.h b/servers/camera_server.h
index 7390129df9..893fdba912 100644
--- a/servers/camera_server.h
+++ b/servers/camera_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 8b5a965738..01f58e37eb 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/display_server.h b/servers/display_server.h
index 2d837dbef9..a84290be77 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h
index 0837e41db8..4ef9dc622f 100644
--- a/servers/display_server_headless.h
+++ b/servers/display_server_headless.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index 85b12f1585..c4c10ebf3b 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index d56c719839..8ab479b8fd 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index b0047a250a..03c75369a6 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index 3aef693ac8..c70d87ec16 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_area_2d.cpp b/servers/physics_2d/godot_area_2d.cpp
index c4060615c9..9937178550 100644
--- a/servers/physics_2d/godot_area_2d.cpp
+++ b/servers/physics_2d/godot_area_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_area_2d.h b/servers/physics_2d/godot_area_2d.h
index 699c1c1bc8..6e8078909b 100644
--- a/servers/physics_2d/godot_area_2d.h
+++ b/servers/physics_2d/godot_area_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_area_pair_2d.cpp b/servers/physics_2d/godot_area_pair_2d.cpp
index bde22aab11..72208d7dff 100644
--- a/servers/physics_2d/godot_area_pair_2d.cpp
+++ b/servers/physics_2d/godot_area_pair_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_area_pair_2d.h b/servers/physics_2d/godot_area_pair_2d.h
index f1290a27d0..ef6c774bc3 100644
--- a/servers/physics_2d/godot_area_pair_2d.h
+++ b/servers/physics_2d/godot_area_pair_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_body_2d.cpp b/servers/physics_2d/godot_body_2d.cpp
index 44da5d4f3b..6873504f70 100644
--- a/servers/physics_2d/godot_body_2d.cpp
+++ b/servers/physics_2d/godot_body_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -569,9 +569,8 @@ void GodotBody2D::integrate_forces(real_t p_step) {
if (!omit_force_integration) {
//overridden by direct state query
- Vector2 force = gravity * mass;
- force += applied_force;
- real_t torque = applied_torque;
+ Vector2 force = gravity * mass + applied_force + constant_force;
+ real_t torque = applied_torque + constant_torque;
real_t damp = 1.0 - p_step * total_linear_damp;
@@ -598,7 +597,10 @@ void GodotBody2D::integrate_forces(real_t p_step) {
}
}
- biased_angular_velocity = 0;
+ applied_force = Vector2();
+ applied_torque = 0.0;
+
+ biased_angular_velocity = 0.0;
biased_linear_velocity = Vector2();
if (do_motion) { //shapes temporarily extend for raycast
diff --git a/servers/physics_2d/godot_body_2d.h b/servers/physics_2d/godot_body_2d.h
index ba4c39737a..1335a19126 100644
--- a/servers/physics_2d/godot_body_2d.h
+++ b/servers/physics_2d/godot_body_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -89,6 +89,9 @@ class GodotBody2D : public GodotCollisionObject2D {
Vector2 applied_force;
real_t applied_torque = 0.0;
+ Vector2 constant_force;
+ real_t constant_torque = 0.0;
+
SelfList<GodotBody2D> active_list;
SelfList<GodotBody2D> mass_properties_update_list;
SelfList<GodotBody2D> direct_state_query_list;
@@ -234,11 +237,49 @@ public:
angular_velocity += _inv_inertia * p_torque;
}
- _FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) {
+ _FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2(), real_t p_max_delta_av = -1.0) {
biased_linear_velocity += p_impulse * _inv_mass;
- biased_angular_velocity += _inv_inertia * (p_position - center_of_mass).cross(p_impulse);
+ if (p_max_delta_av != 0.0) {
+ real_t delta_av = _inv_inertia * (p_position - center_of_mass).cross(p_impulse);
+ if (p_max_delta_av > 0 && delta_av > p_max_delta_av) {
+ delta_av = p_max_delta_av;
+ }
+ biased_angular_velocity += delta_av;
+ }
+ }
+
+ _FORCE_INLINE_ void apply_central_force(const Vector2 &p_force) {
+ applied_force += p_force;
+ }
+
+ _FORCE_INLINE_ void apply_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) {
+ applied_force += p_force;
+ applied_torque += (p_position - center_of_mass).cross(p_force);
+ }
+
+ _FORCE_INLINE_ void apply_torque(real_t p_torque) {
+ applied_torque += p_torque;
+ }
+
+ _FORCE_INLINE_ void add_constant_central_force(const Vector2 &p_force) {
+ constant_force += p_force;
+ }
+
+ _FORCE_INLINE_ void add_constant_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) {
+ constant_force += p_force;
+ constant_torque += (p_position - center_of_mass).cross(p_force);
}
+ _FORCE_INLINE_ void add_constant_torque(real_t p_torque) {
+ constant_torque += p_torque;
+ }
+
+ void set_constant_force(const Vector2 &p_force) { constant_force = p_force; }
+ Vector2 get_constant_force() const { return constant_force; }
+
+ void set_constant_torque(real_t p_torque) { constant_torque = p_torque; }
+ real_t get_constant_torque() const { return constant_torque; }
+
void set_active(bool p_active);
_FORCE_INLINE_ bool is_active() const { return active; }
@@ -258,25 +299,6 @@ public:
void set_state(PhysicsServer2D::BodyState p_state, const Variant &p_variant);
Variant get_state(PhysicsServer2D::BodyState p_state) const;
- void set_applied_force(const Vector2 &p_force) { applied_force = p_force; }
- Vector2 get_applied_force() const { return applied_force; }
-
- void set_applied_torque(real_t p_torque) { applied_torque = p_torque; }
- real_t get_applied_torque() const { return applied_torque; }
-
- _FORCE_INLINE_ void add_central_force(const Vector2 &p_force) {
- applied_force += p_force;
- }
-
- _FORCE_INLINE_ void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) {
- applied_force += p_force;
- applied_torque += (p_position - center_of_mass).cross(p_force);
- }
-
- _FORCE_INLINE_ void add_torque(real_t p_torque) {
- applied_torque += p_torque;
- }
-
_FORCE_INLINE_ void set_continuous_collision_detection_mode(PhysicsServer2D::CCDMode p_mode) { continuous_cd_mode = p_mode; }
_FORCE_INLINE_ PhysicsServer2D::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; }
diff --git a/servers/physics_2d/godot_body_direct_state_2d.cpp b/servers/physics_2d/godot_body_direct_state_2d.cpp
index 9c9bd56268..cde6e8c991 100644
--- a/servers/physics_2d/godot_body_direct_state_2d.cpp
+++ b/servers/physics_2d/godot_body_direct_state_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -92,34 +92,71 @@ Vector2 GodotPhysicsDirectBodyState2D::get_velocity_at_local_position(const Vect
return body->get_velocity_in_local_point(p_position);
}
-void GodotPhysicsDirectBodyState2D::add_central_force(const Vector2 &p_force) {
+void GodotPhysicsDirectBodyState2D::apply_central_impulse(const Vector2 &p_impulse) {
body->wakeup();
- body->add_central_force(p_force);
+ body->apply_central_impulse(p_impulse);
}
-void GodotPhysicsDirectBodyState2D::add_force(const Vector2 &p_force, const Vector2 &p_position) {
+void GodotPhysicsDirectBodyState2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position) {
body->wakeup();
- body->add_force(p_force, p_position);
+ body->apply_impulse(p_impulse, p_position);
}
-void GodotPhysicsDirectBodyState2D::add_torque(real_t p_torque) {
+void GodotPhysicsDirectBodyState2D::apply_torque_impulse(real_t p_torque) {
body->wakeup();
- body->add_torque(p_torque);
+ body->apply_torque_impulse(p_torque);
}
-void GodotPhysicsDirectBodyState2D::apply_central_impulse(const Vector2 &p_impulse) {
+void GodotPhysicsDirectBodyState2D::apply_central_force(const Vector2 &p_force) {
body->wakeup();
- body->apply_central_impulse(p_impulse);
+ body->apply_central_force(p_force);
}
-void GodotPhysicsDirectBodyState2D::apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position) {
+void GodotPhysicsDirectBodyState2D::apply_force(const Vector2 &p_force, const Vector2 &p_position) {
body->wakeup();
- body->apply_impulse(p_impulse, p_position);
+ body->apply_force(p_force, p_position);
}
-void GodotPhysicsDirectBodyState2D::apply_torque_impulse(real_t p_torque) {
+void GodotPhysicsDirectBodyState2D::apply_torque(real_t p_torque) {
body->wakeup();
- body->apply_torque_impulse(p_torque);
+ body->apply_torque(p_torque);
+}
+
+void GodotPhysicsDirectBodyState2D::add_constant_central_force(const Vector2 &p_force) {
+ body->wakeup();
+ body->add_constant_central_force(p_force);
+}
+
+void GodotPhysicsDirectBodyState2D::add_constant_force(const Vector2 &p_force, const Vector2 &p_position) {
+ body->wakeup();
+ body->add_constant_force(p_force, p_position);
+}
+
+void GodotPhysicsDirectBodyState2D::add_constant_torque(real_t p_torque) {
+ body->wakeup();
+ body->add_constant_torque(p_torque);
+}
+
+void GodotPhysicsDirectBodyState2D::set_constant_force(const Vector2 &p_force) {
+ if (!p_force.is_equal_approx(Vector2())) {
+ body->wakeup();
+ }
+ body->set_constant_force(p_force);
+}
+
+Vector2 GodotPhysicsDirectBodyState2D::get_constant_force() const {
+ return body->get_constant_force();
+}
+
+void GodotPhysicsDirectBodyState2D::set_constant_torque(real_t p_torque) {
+ if (!Math::is_zero_approx(p_torque)) {
+ body->wakeup();
+ }
+ body->set_constant_torque(p_torque);
+}
+
+real_t GodotPhysicsDirectBodyState2D::get_constant_torque() const {
+ return body->get_constant_torque();
}
void GodotPhysicsDirectBodyState2D::set_sleep_state(bool p_enable) {
diff --git a/servers/physics_2d/godot_body_direct_state_2d.h b/servers/physics_2d/godot_body_direct_state_2d.h
index ff25205d52..a2c0a87989 100644
--- a/servers/physics_2d/godot_body_direct_state_2d.h
+++ b/servers/physics_2d/godot_body_direct_state_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,13 +61,24 @@ public:
virtual Vector2 get_velocity_at_local_position(const Vector2 &p_position) const override;
- virtual void add_central_force(const Vector2 &p_force) override;
- virtual void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) override;
- virtual void add_torque(real_t p_torque) override;
virtual void apply_central_impulse(const Vector2 &p_impulse) override;
virtual void apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) override;
virtual void apply_torque_impulse(real_t p_torque) override;
+ virtual void apply_central_force(const Vector2 &p_force) override;
+ virtual void apply_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) override;
+ virtual void apply_torque(real_t p_torque) override;
+
+ virtual void add_constant_central_force(const Vector2 &p_force) override;
+ virtual void add_constant_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) override;
+ virtual void add_constant_torque(real_t p_torque) override;
+
+ virtual void set_constant_force(const Vector2 &p_force) override;
+ virtual Vector2 get_constant_force() const override;
+
+ virtual void set_constant_torque(real_t p_torque) override;
+ virtual real_t get_constant_torque() const override;
+
virtual void set_sleep_state(bool p_enable) override;
virtual bool is_sleeping() const override;
diff --git a/servers/physics_2d/godot_body_pair_2d.cpp b/servers/physics_2d/godot_body_pair_2d.cpp
index 67b0f21456..1986191cc3 100644
--- a/servers/physics_2d/godot_body_pair_2d.cpp
+++ b/servers/physics_2d/godot_body_pair_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -34,6 +34,9 @@
#define ACCUMULATE_IMPULSES
+#define MIN_VELOCITY 0.001
+#define MAX_BIAS_ROTATION (Math_PI / 8)
+
void GodotBodyPair2D::_add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self) {
GodotBodyPair2D *self = (GodotBodyPair2D *)p_self;
@@ -41,8 +44,6 @@ void GodotBodyPair2D::_add_contact(const Vector2 &p_point_A, const Vector2 &p_po
}
void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B) {
- // check if we already have the contact
-
Vector2 local_A = A->get_inv_transform().basis_xform(p_point_A);
Vector2 local_B = B->get_inv_transform().basis_xform(p_point_B - offset_B);
@@ -51,46 +52,48 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
ERR_FAIL_COND(new_index >= (MAX_CONTACTS + 1));
Contact contact;
-
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_tangent_impulse = 0;
contact.local_A = local_A;
contact.local_B = local_B;
- contact.reused = true;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0; // will be computed in setup()
-
- // attempt to determine if the contact will be reused
+ contact.used = true;
+ // Attempt to determine if the contact will be reused.
real_t recycle_radius_2 = space->get_contact_recycle_radius() * space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (
- c.local_A.distance_squared_to(local_A) < (recycle_radius_2) &&
+ if (c.local_A.distance_squared_to(local_A) < (recycle_radius_2) &&
c.local_B.distance_squared_to(local_B) < (recycle_radius_2)) {
contact.acc_normal_impulse = c.acc_normal_impulse;
contact.acc_tangent_impulse = c.acc_tangent_impulse;
contact.acc_bias_impulse = c.acc_bias_impulse;
- new_index = i;
- break;
+ contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass;
+ c = contact;
+ return;
}
}
- // figure out if the contact amount must be reduced to fit the new contact
-
+ // Figure out if the contact amount must be reduced to fit the new contact.
if (new_index == MAX_CONTACTS) {
- // remove the contact with the minimum depth
-
- int least_deep = -1;
- real_t min_depth = 1e10;
+ // Remove the contact with the minimum depth.
const Transform2D &transform_A = A->get_transform();
const Transform2D &transform_B = B->get_transform();
- for (int i = 0; i <= contact_count; i++) {
- Contact &c = (i == contact_count) ? contact : contacts[i];
+ int least_deep = -1;
+ real_t min_depth;
+
+ // Start with depth for new contact.
+ {
+ Vector2 global_A = transform_A.basis_xform(contact.local_A);
+ Vector2 global_B = transform_B.basis_xform(contact.local_B) + offset_B;
+
+ Vector2 axis = global_A - global_B;
+ min_depth = axis.dot(contact.normal);
+ }
+
+ for (int i = 0; i < contact_count; i++) {
+ const Contact &c = contacts[i];
Vector2 global_A = transform_A.basis_xform(c.local_A);
Vector2 global_B = transform_B.basis_xform(c.local_B) + offset_B;
@@ -103,10 +106,8 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
}
}
- ERR_FAIL_COND(least_deep == -1);
-
- if (least_deep < contact_count) { //replace the last deep contact by the new one
-
+ if (least_deep > -1) {
+ // Replace the least deep contact by the new one.
contacts[least_deep] = contact;
}
@@ -114,15 +115,11 @@ void GodotBodyPair2D::_contact_added_callback(const Vector2 &p_point_A, const Ve
}
contacts[new_index] = contact;
-
- if (new_index == contact_count) {
- contact_count++;
- }
+ contact_count++;
}
void GodotBodyPair2D::_validate_contacts() {
- //make sure to erase contacts that are no longer valid
-
+ // Make sure to erase contacts that are no longer valid.
real_t max_separation = space->get_contact_max_separation();
real_t max_separation2 = max_separation * max_separation;
@@ -133,11 +130,11 @@ void GodotBodyPair2D::_validate_contacts() {
Contact &c = contacts[i];
bool erase = false;
- if (!c.reused) {
- //was left behind in previous frame
+ if (!c.used) {
+ // Was left behind in previous frame.
erase = true;
} else {
- c.reused = false;
+ c.used = false;
Vector2 global_A = transform_A.basis_xform(c.local_A);
Vector2 global_B = transform_B.basis_xform(c.local_B) + offset_B;
@@ -150,10 +147,10 @@ void GodotBodyPair2D::_validate_contacts() {
}
if (erase) {
- // contact no longer needed, remove
+ // Contact no longer needed, remove.
if ((i + 1) < contact_count) {
- // swap with the last one
+ // Swap with the last one.
SWAP(contacts[i], contacts[contact_count - 1]);
}
@@ -163,7 +160,7 @@ void GodotBodyPair2D::_validate_contacts() {
}
}
-bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, const Transform2D &p_xform_A, GodotBody2D *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result) {
+bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, const Transform2D &p_xform_A, GodotBody2D *p_B, int p_shape_B, const Transform2D &p_xform_B) {
Vector2 motion = p_A->get_linear_velocity() * p_step;
real_t mlen = motion.length();
if (mlen < CMP_EPSILON) {
@@ -174,14 +171,18 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A,
real_t min, max;
p_A->get_shape(p_shape_A)->project_rangev(mnormal, p_xform_A, min, max);
- bool fast_object = mlen > (max - min) * 0.3; //going too fast in that direction
- if (!fast_object) { //did it move enough in this direction to even attempt raycast? let's say it should move more than 1/3 the size of the object in that axis
+ // Did it move enough in this direction to even attempt raycast?
+ // Let's say it should move more than 1/3 the size of the object in that axis.
+ bool fast_object = mlen > (max - min) * 0.3;
+ if (!fast_object) {
return false;
}
- //cast a segment from support in motion normal, in the same direction of motion by motion length
- //support is the worst case collision point, so real collision happened before
+ // Going too fast in that direction.
+
+ // Cast a segment from support in motion normal, in the same direction of motion by motion length.
+ // Support is the worst case collision point, so real collision happened before.
int a;
Vector2 s[2];
p_A->get_shape(p_shape_A)->get_supports(p_xform_A.basis_xform(mnormal).normalized(), s, a);
@@ -190,7 +191,8 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A,
Transform2D from_inv = p_xform_B.affine_inverse();
- Vector2 local_from = from_inv.xform(from - mnormal * mlen * 0.1); //start from a little inside the bounding box
+ // Start from a little inside the bounding box.
+ Vector2 local_from = from_inv.xform(from - mnormal * mlen * 0.1);
Vector2 local_to = from_inv.xform(to);
Vector2 rpos, rnorm;
@@ -198,20 +200,22 @@ bool GodotBodyPair2D::_test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A,
return false;
}
- //ray hit something
+ // Check one-way collision based on motion direction.
+ if (p_A->get_shape(p_shape_A)->allows_one_way_collision() && p_B->is_shape_set_as_one_way_collision(p_shape_B)) {
+ Vector2 direction = p_xform_B.get_axis(1).normalized();
+ if (direction.dot(mnormal) < CMP_EPSILON) {
+ collided = false;
+ oneway_disabled = true;
+ return false;
+ }
+ }
+ // Shorten the linear velocity so it does not hit, but gets close enough,
+ // next frame will hit softly or soft enough.
Vector2 hitpos = p_xform_B.xform(rpos);
- Vector2 contact_A = to;
- Vector2 contact_B = hitpos;
-
- //create a contact
-
- if (p_swap_result) {
- _contact_added_callback(contact_B, contact_A);
- } else {
- _contact_added_callback(contact_A, contact_B);
- }
+ real_t newlen = hitpos.distance_to(from) - (max - min) * 0.01;
+ p_A->set_linear_velocity(mnormal * (newlen / p_step));
return true;
}
@@ -225,6 +229,8 @@ real_t combine_friction(GodotBody2D *A, GodotBody2D *B) {
}
bool GodotBodyPair2D::setup(real_t p_step) {
+ check_ccd = false;
+
if (!A->interacts_with(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self())) {
collided = false;
return false;
@@ -272,24 +278,19 @@ bool GodotBodyPair2D::setup(real_t p_step) {
collided = GodotCollisionSolver2D::solve(shape_A_ptr, xform_A, motion_A, shape_B_ptr, xform_B, motion_B, _add_contact, this, &sep_axis);
if (!collided) {
- //test ccd (currently just a raycast)
+ oneway_disabled = false;
if (A->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && collide_A) {
- if (_test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B)) {
- collided = true;
- }
+ check_ccd = true;
+ return true;
}
if (B->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && collide_B) {
- if (_test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A, true)) {
- collided = true;
- }
+ check_ccd = true;
+ return true;
}
- if (!collided) {
- oneway_disabled = false;
- return false;
- }
+ return false;
}
if (oneway_disabled) {
@@ -302,9 +303,6 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
if (c.normal.dot(direction) > -CMP_EPSILON) { //greater (normal inverted)
continue;
}
@@ -323,9 +321,6 @@ bool GodotBodyPair2D::setup(real_t p_step) {
bool valid = false;
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused) {
- continue;
- }
if (c.normal.dot(direction) < CMP_EPSILON) { //less (normal ok)
continue;
}
@@ -344,13 +339,35 @@ bool GodotBodyPair2D::setup(real_t p_step) {
}
bool GodotBodyPair2D::pre_solve(real_t p_step) {
- if (!collided || oneway_disabled) {
+ if (oneway_disabled) {
+ return false;
+ }
+
+ if (!collided) {
+ if (check_ccd) {
+ const Vector2 &offset_A = A->get_transform().get_origin();
+ Transform2D xform_Au = A->get_transform().untranslated();
+ Transform2D xform_A = xform_Au * A->get_shape_transform(shape_A);
+
+ Transform2D xform_Bu = B->get_transform();
+ xform_Bu.elements[2] -= offset_A;
+ Transform2D xform_B = xform_Bu * B->get_shape_transform(shape_B);
+
+ if (A->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && collide_A) {
+ _test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B);
+ }
+
+ if (B->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && collide_B) {
+ _test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A);
+ }
+ }
+
return false;
}
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = 0.3;
+ real_t bias = space->get_contact_bias();
GodotShape2D *shape_A_ptr = A->get_shape(shape_A);
GodotShape2D *shape_B_ptr = B->get_shape(shape_B);
@@ -389,7 +406,7 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
Vector2 axis = global_A - global_B;
real_t depth = axis.dot(c.normal);
- if (depth <= 0.0 || !c.reused) {
+ if (depth <= 0.0) {
continue;
}
@@ -400,8 +417,8 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
}
#endif
- c.rA = global_A;
- c.rB = global_B - offset_B;
+ c.rA = global_A - A->get_center_of_mass();
+ c.rB = global_B - B->get_center_of_mass() - offset_B;
if (A->can_report_contacts()) {
Vector2 crB(-B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x);
@@ -434,7 +451,6 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
c.bias = -bias * inv_dt * MIN(0.0f, -depth + max_penetration);
c.depth = depth;
- //c.acc_bias_impulse=0;
#ifdef ACCUMULATE_IMPULSES
{
@@ -442,10 +458,10 @@ bool GodotBodyPair2D::pre_solve(real_t p_step) {
Vector2 P = c.acc_normal_impulse * c.normal + c.acc_tangent_impulse * tangent;
if (collide_A) {
- A->apply_impulse(-P, c.rA);
+ A->apply_impulse(-P, c.rA + A->get_center_of_mass());
}
if (collide_B) {
- B->apply_impulse(P, c.rB);
+ B->apply_impulse(P, c.rB + B->get_center_of_mass());
}
}
#endif
@@ -470,6 +486,11 @@ void GodotBodyPair2D::solve(real_t p_step) {
return;
}
+ const real_t max_bias_av = MAX_BIAS_ROTATION / p_step;
+
+ real_t inv_mass_A = collide_A ? A->get_inv_mass() : 0.0;
+ real_t inv_mass_B = collide_B ? B->get_inv_mass() : 0.0;
+
for (int i = 0; i < contact_count; ++i) {
Contact &c = contacts[i];
@@ -489,6 +510,7 @@ void GodotBodyPair2D::solve(real_t p_step) {
real_t vn = dv.dot(c.normal);
real_t vbn = dbv.dot(c.normal);
+
Vector2 tangent = c.normal.orthogonal();
real_t vt = dv.dot(tangent);
@@ -499,10 +521,31 @@ void GodotBodyPair2D::solve(real_t p_step) {
Vector2 jb = c.normal * (c.acc_bias_impulse - jbnOld);
if (collide_A) {
- A->apply_bias_impulse(-jb, c.rA);
+ A->apply_bias_impulse(-jb, c.rA + A->get_center_of_mass(), max_bias_av);
}
if (collide_B) {
- B->apply_bias_impulse(jb, c.rB);
+ B->apply_bias_impulse(jb, c.rB + B->get_center_of_mass(), max_bias_av);
+ }
+
+ crbA = Vector2(-A->get_biased_angular_velocity() * c.rA.y, A->get_biased_angular_velocity() * c.rA.x);
+ crbB = Vector2(-B->get_biased_angular_velocity() * c.rB.y, B->get_biased_angular_velocity() * c.rB.x);
+ dbv = B->get_biased_linear_velocity() + crbB - A->get_biased_linear_velocity() - crbA;
+
+ vbn = dbv.dot(c.normal);
+
+ if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) {
+ real_t jbn_com = (-vbn + c.bias) / (inv_mass_A + inv_mass_B);
+ real_t jbnOld_com = c.acc_bias_impulse_center_of_mass;
+ c.acc_bias_impulse_center_of_mass = MAX(jbnOld_com + jbn_com, 0.0f);
+
+ Vector2 jb_com = c.normal * (c.acc_bias_impulse_center_of_mass - jbnOld_com);
+
+ if (collide_A) {
+ A->apply_bias_impulse(-jb_com, A->get_center_of_mass(), 0.0f);
+ }
+ if (collide_B) {
+ B->apply_bias_impulse(jb_com, B->get_center_of_mass(), 0.0f);
+ }
}
real_t jn = -(c.bounce + vn) * c.mass_normal;
@@ -519,10 +562,10 @@ void GodotBodyPair2D::solve(real_t p_step) {
Vector2 j = c.normal * (c.acc_normal_impulse - jnOld) + tangent * (c.acc_tangent_impulse - jtOld);
if (collide_A) {
- A->apply_impulse(-j, c.rA);
+ A->apply_impulse(-j, c.rA + A->get_center_of_mass());
}
if (collide_B) {
- B->apply_impulse(j, c.rB);
+ B->apply_impulse(j, c.rB + B->get_center_of_mass());
}
}
}
diff --git a/servers/physics_2d/godot_body_pair_2d.h b/servers/physics_2d/godot_body_pair_2d.h
index 0938ab542b..1c0f61be26 100644
--- a/servers/physics_2d/godot_body_pair_2d.h
+++ b/servers/physics_2d/godot_body_pair_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -62,13 +62,14 @@ class GodotBodyPair2D : public GodotConstraint2D {
real_t acc_normal_impulse = 0.0; // accumulated normal impulse (Pn)
real_t acc_tangent_impulse = 0.0; // accumulated tangent impulse (Pt)
real_t acc_bias_impulse = 0.0; // accumulated normal impulse for position bias (Pnb)
+ real_t acc_bias_impulse_center_of_mass = 0.0; // accumulated normal impulse for position bias applied to com
real_t mass_normal, mass_tangent = 0.0;
real_t bias = 0.0;
real_t depth = 0.0;
bool active = false;
+ bool used = false;
Vector2 rA, rB;
- bool reused = false;
real_t bounce = 0.0;
};
@@ -78,10 +79,11 @@ class GodotBodyPair2D : public GodotConstraint2D {
Contact contacts[MAX_CONTACTS];
int contact_count = 0;
bool collided = false;
+ bool check_ccd = false;
bool oneway_disabled = false;
bool report_contacts_only = false;
- bool _test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, const Transform2D &p_xform_A, GodotBody2D *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result = false);
+ bool _test_ccd(real_t p_step, GodotBody2D *p_A, int p_shape_A, const Transform2D &p_xform_A, GodotBody2D *p_B, int p_shape_B, const Transform2D &p_xform_B);
void _validate_contacts();
static void _add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self);
_FORCE_INLINE_ void _contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B);
diff --git a/servers/physics_2d/godot_broad_phase_2d.cpp b/servers/physics_2d/godot_broad_phase_2d.cpp
index 4b35f8d996..e734c24f88 100644
--- a/servers/physics_2d/godot_broad_phase_2d.cpp
+++ b/servers/physics_2d/godot_broad_phase_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_broad_phase_2d.h b/servers/physics_2d/godot_broad_phase_2d.h
index 7017a6e41f..abab087045 100644
--- a/servers/physics_2d/godot_broad_phase_2d.h
+++ b/servers/physics_2d/godot_broad_phase_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp
index 9ec6b0a6b7..5a96dae8ca 100644
--- a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp
+++ b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.h b/servers/physics_2d/godot_broad_phase_2d_bvh.h
index 19b49f3499..d77e0574eb 100644
--- a/servers/physics_2d/godot_broad_phase_2d_bvh.h
+++ b/servers/physics_2d/godot_broad_phase_2d_bvh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_collision_object_2d.cpp b/servers/physics_2d/godot_collision_object_2d.cpp
index 719d9c874a..35027e0f69 100644
--- a/servers/physics_2d/godot_collision_object_2d.cpp
+++ b/servers/physics_2d/godot_collision_object_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_collision_object_2d.h b/servers/physics_2d/godot_collision_object_2d.h
index 7233857808..1e9baad8d9 100644
--- a/servers/physics_2d/godot_collision_object_2d.h
+++ b/servers/physics_2d/godot_collision_object_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_collision_solver_2d.cpp b/servers/physics_2d/godot_collision_solver_2d.cpp
index 25371b9885..263d6d939f 100644
--- a/servers/physics_2d/godot_collision_solver_2d.cpp
+++ b/servers/physics_2d/godot_collision_solver_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_collision_solver_2d.h b/servers/physics_2d/godot_collision_solver_2d.h
index f10815a444..bd90641f04 100644
--- a/servers/physics_2d/godot_collision_solver_2d.h
+++ b/servers/physics_2d/godot_collision_solver_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_collision_solver_2d_sat.cpp b/servers/physics_2d/godot_collision_solver_2d_sat.cpp
index 63053e8259..a965795bee 100644
--- a/servers/physics_2d/godot_collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/godot_collision_solver_2d_sat.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_collision_solver_2d_sat.h b/servers/physics_2d/godot_collision_solver_2d_sat.h
index 1517b90a19..3d8e29c41a 100644
--- a/servers/physics_2d/godot_collision_solver_2d_sat.h
+++ b/servers/physics_2d/godot_collision_solver_2d_sat.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_constraint_2d.h b/servers/physics_2d/godot_constraint_2d.h
index 84f975e583..d9bf035c2b 100644
--- a/servers/physics_2d/godot_constraint_2d.h
+++ b/servers/physics_2d/godot_constraint_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_joints_2d.cpp b/servers/physics_2d/godot_joints_2d.cpp
index 7c08c2f4b4..0876184d8c 100644
--- a/servers/physics_2d/godot_joints_2d.cpp
+++ b/servers/physics_2d/godot_joints_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_joints_2d.h b/servers/physics_2d/godot_joints_2d.h
index 4c97190d01..acaaf0f629 100644
--- a/servers/physics_2d/godot_joints_2d.h
+++ b/servers/physics_2d/godot_joints_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp
index 8ac27077fc..5e099e27ec 100644
--- a/servers/physics_2d/godot_physics_server_2d.cpp
+++ b/servers/physics_2d/godot_physics_server_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -669,68 +669,68 @@ void GodotPhysicsServer2D::body_attach_object_instance_id(RID p_body, ObjectID p
ERR_FAIL_COND(!body);
body->set_instance_id(p_id);
-};
+}
ObjectID GodotPhysicsServer2D::body_get_object_instance_id(RID p_body) const {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, ObjectID());
return body->get_instance_id();
-};
+}
void GodotPhysicsServer2D::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
body->set_canvas_instance_id(p_id);
-};
+}
ObjectID GodotPhysicsServer2D::body_get_canvas_instance_id(RID p_body) const {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, ObjectID());
return body->get_canvas_instance_id();
-};
+}
void GodotPhysicsServer2D::body_set_collision_layer(RID p_body, uint32_t p_layer) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
body->set_collision_layer(p_layer);
-};
+}
uint32_t GodotPhysicsServer2D::body_get_collision_layer(RID p_body) const {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_collision_layer();
-};
+}
void GodotPhysicsServer2D::body_set_collision_mask(RID p_body, uint32_t p_mask) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
body->set_collision_mask(p_mask);
-};
+}
uint32_t GodotPhysicsServer2D::body_get_collision_mask(RID p_body) const {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_collision_mask();
-};
+}
void GodotPhysicsServer2D::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
body->set_param(p_param, p_value);
-};
+}
Variant GodotPhysicsServer2D::body_get_param(RID p_body, BodyParameter p_param) const {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_param(p_param);
-};
+}
void GodotPhysicsServer2D::body_reset_mass_properties(RID p_body) {
GodotBody2D *body = body_owner.get_or_null(p_body);
@@ -744,95 +744,123 @@ void GodotPhysicsServer2D::body_set_state(RID p_body, BodyState p_state, const V
ERR_FAIL_COND(!body);
body->set_state(p_state, p_variant);
-};
+}
Variant GodotPhysicsServer2D::body_get_state(RID p_body, BodyState p_state) const {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, Variant());
return body->get_state(p_state);
-};
+}
-void GodotPhysicsServer2D::body_set_applied_force(RID p_body, const Vector2 &p_force) {
+void GodotPhysicsServer2D::body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->set_applied_force(p_force);
+ body->apply_central_impulse(p_impulse);
body->wakeup();
-};
+}
-Vector2 GodotPhysicsServer2D::body_get_applied_force(RID p_body) const {
+void GodotPhysicsServer2D::body_apply_torque_impulse(RID p_body, real_t p_torque) {
GodotBody2D *body = body_owner.get_or_null(p_body);
- ERR_FAIL_COND_V(!body, Vector2());
- return body->get_applied_force();
-};
+ ERR_FAIL_COND(!body);
+
+ _update_shapes();
+
+ body->apply_torque_impulse(p_torque);
+ body->wakeup();
+}
-void GodotPhysicsServer2D::body_set_applied_torque(RID p_body, real_t p_torque) {
+void GodotPhysicsServer2D::body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->set_applied_torque(p_torque);
+ _update_shapes();
+
+ body->apply_impulse(p_impulse, p_position);
body->wakeup();
-};
+}
-real_t GodotPhysicsServer2D::body_get_applied_torque(RID p_body) const {
+void GodotPhysicsServer2D::body_apply_central_force(RID p_body, const Vector2 &p_force) {
GodotBody2D *body = body_owner.get_or_null(p_body);
- ERR_FAIL_COND_V(!body, 0);
+ ERR_FAIL_COND(!body);
- return body->get_applied_torque();
-};
+ body->apply_central_force(p_force);
+ body->wakeup();
+}
-void GodotPhysicsServer2D::body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) {
+void GodotPhysicsServer2D::body_apply_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->apply_central_impulse(p_impulse);
+ body->apply_force(p_force, p_position);
body->wakeup();
}
-void GodotPhysicsServer2D::body_apply_torque_impulse(RID p_body, real_t p_torque) {
+void GodotPhysicsServer2D::body_apply_torque(RID p_body, real_t p_torque) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- _update_shapes();
-
- body->apply_torque_impulse(p_torque);
+ body->apply_torque(p_torque);
body->wakeup();
}
-void GodotPhysicsServer2D::body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position) {
+void GodotPhysicsServer2D::body_add_constant_central_force(RID p_body, const Vector2 &p_force) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- _update_shapes();
-
- body->apply_impulse(p_impulse, p_position);
+ body->add_constant_central_force(p_force);
body->wakeup();
-};
+}
-void GodotPhysicsServer2D::body_add_central_force(RID p_body, const Vector2 &p_force) {
+void GodotPhysicsServer2D::body_add_constant_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->add_central_force(p_force);
+ body->add_constant_force(p_force, p_position);
body->wakeup();
-};
+}
-void GodotPhysicsServer2D::body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position) {
+void GodotPhysicsServer2D::body_add_constant_torque(RID p_body, real_t p_torque) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->add_force(p_force, p_position);
+ body->add_constant_torque(p_torque);
body->wakeup();
-};
+}
-void GodotPhysicsServer2D::body_add_torque(RID p_body, real_t p_torque) {
+void GodotPhysicsServer2D::body_set_constant_force(RID p_body, const Vector2 &p_force) {
GodotBody2D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->add_torque(p_torque);
- body->wakeup();
-};
+ body->set_constant_force(p_force);
+ if (!p_force.is_equal_approx(Vector2())) {
+ body->wakeup();
+ }
+}
+
+Vector2 GodotPhysicsServer2D::body_get_constant_force(RID p_body) const {
+ GodotBody2D *body = body_owner.get_or_null(p_body);
+ ERR_FAIL_COND_V(!body, Vector2());
+ return body->get_constant_force();
+}
+
+void GodotPhysicsServer2D::body_set_constant_torque(RID p_body, real_t p_torque) {
+ GodotBody2D *body = body_owner.get_or_null(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_constant_torque(p_torque);
+ if (!Math::is_zero_approx(p_torque)) {
+ body->wakeup();
+ }
+}
+
+real_t GodotPhysicsServer2D::body_get_constant_torque(RID p_body) const {
+ GodotBody2D *body = body_owner.get_or_null(p_body);
+ ERR_FAIL_COND_V(!body, 0);
+
+ return body->get_constant_torque();
+}
void GodotPhysicsServer2D::body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) {
GodotBody2D *body = body_owner.get_or_null(p_body);
@@ -1214,21 +1242,16 @@ void GodotPhysicsServer2D::free(RID p_rid) {
} else {
ERR_FAIL_MSG("Invalid ID.");
}
-};
+}
void GodotPhysicsServer2D::set_active(bool p_active) {
active = p_active;
-};
-
-void GodotPhysicsServer2D::set_collision_iterations(int p_iterations) {
- iterations = p_iterations;
-};
+}
void GodotPhysicsServer2D::init() {
doing_sync = false;
- iterations = 8; // 8?
stepper = memnew(GodotStep2D);
-};
+}
void GodotPhysicsServer2D::step(real_t p_step) {
if (!active) {
@@ -1241,16 +1264,16 @@ void GodotPhysicsServer2D::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step((GodotSpace2D *)E->get(), p_step, iterations);
+ stepper->step((GodotSpace2D *)E->get(), p_step);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
}
-};
+}
void GodotPhysicsServer2D::sync() {
doing_sync = true;
-};
+}
void GodotPhysicsServer2D::flush_queries() {
if (!active) {
@@ -1308,7 +1331,7 @@ void GodotPhysicsServer2D::end_sync() {
void GodotPhysicsServer2D::finish() {
memdelete(stepper);
-};
+}
void GodotPhysicsServer2D::_update_shapes() {
while (pending_shape_update_list.first()) {
@@ -1340,4 +1363,4 @@ GodotPhysicsServer2D::GodotPhysicsServer2D(bool p_using_threads) {
GodotBroadPhase2D::create_func = GodotBroadPhase2DBVH::_create;
using_threads = p_using_threads;
-};
+}
diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h
index 1f544fee72..0a84caadc5 100644
--- a/servers/physics_2d/godot_physics_server_2d.h
+++ b/servers/physics_2d/godot_physics_server_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -45,7 +45,6 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
friend class GodotPhysicsDirectSpaceState2D;
friend class GodotPhysicsDirectBodyState2D;
bool active = true;
- int iterations = 0;
bool doing_sync = false;
int island_count = 0;
@@ -208,19 +207,24 @@ public:
virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override;
virtual Variant body_get_state(RID p_body, BodyState p_state) const override;
- virtual void body_set_applied_force(RID p_body, const Vector2 &p_force) override;
- virtual Vector2 body_get_applied_force(RID p_body) const override;
-
- virtual void body_set_applied_torque(RID p_body, real_t p_torque) override;
- virtual real_t body_get_applied_torque(RID p_body) const override;
-
- virtual void body_add_central_force(RID p_body, const Vector2 &p_force) override;
- virtual void body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) override;
- virtual void body_add_torque(RID p_body, real_t p_torque) override;
-
virtual void body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) override;
virtual void body_apply_torque_impulse(RID p_body, real_t p_torque) override;
virtual void body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) override;
+
+ virtual void body_apply_central_force(RID p_body, const Vector2 &p_force) override;
+ virtual void body_apply_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) override;
+ virtual void body_apply_torque(RID p_body, real_t p_torque) override;
+
+ virtual void body_add_constant_central_force(RID p_body, const Vector2 &p_force) override;
+ virtual void body_add_constant_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) override;
+ virtual void body_add_constant_torque(RID p_body, real_t p_torque) override;
+
+ virtual void body_set_constant_force(RID p_body, const Vector2 &p_force) override;
+ virtual Vector2 body_get_constant_force(RID p_body) const override;
+
+ virtual void body_set_constant_torque(RID p_body, real_t p_torque) override;
+ virtual real_t body_get_constant_torque(RID p_body) const override;
+
virtual void body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) override;
virtual void body_add_collision_exception(RID p_body, RID p_body_b) override;
@@ -283,8 +287,6 @@ public:
virtual void end_sync() override;
virtual void finish() override;
- virtual void set_collision_iterations(int p_iterations) override;
-
virtual bool is_flushing_queries() const override { return flushing_queries; }
int get_process_info(ProcessInfo p_info) override;
diff --git a/servers/physics_2d/godot_shape_2d.cpp b/servers/physics_2d/godot_shape_2d.cpp
index 3604004324..1e8799a727 100644
--- a/servers/physics_2d/godot_shape_2d.cpp
+++ b/servers/physics_2d/godot_shape_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_shape_2d.h b/servers/physics_2d/godot_shape_2d.h
index 25d113aafb..fb52cbce20 100644
--- a/servers/physics_2d/godot_shape_2d.h
+++ b/servers/physics_2d/godot_shape_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp
index 7a5eb26bb3..5c2bda340b 100644
--- a/servers/physics_2d/godot_space_2d.cpp
+++ b/servers/physics_2d/godot_space_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,7 @@
#include "core/os/os.h"
#include "core/templates/pair.h"
+#define TEST_MOTION_MARGIN_MIN_VALUE 0.0001
#define TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR 0.05
_FORCE_INLINE_ static bool _can_collide_with(GodotCollisionObject2D *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
@@ -439,9 +440,11 @@ bool GodotPhysicsDirectSpaceState2D::rest_info(const ShapeParameters &p_paramete
GodotShape2D *shape = GodotPhysicsServer2D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0);
+ real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE);
+
Rect2 aabb = p_parameters.transform.xform(shape->get_aabb());
aabb = aabb.merge(Rect2(aabb.position + p_parameters.motion, aabb.size)); //motion
- aabb = aabb.grow(p_parameters.margin);
+ aabb = aabb.grow(margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace2D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -449,7 +452,7 @@ bool GodotPhysicsDirectSpaceState2D::rest_info(const ShapeParameters &p_paramete
// Allowed depth can't be lower than motion length, in order to handle contacts at low speed.
real_t motion_length = p_parameters.motion.length();
- real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
+ real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
rcd.min_allowed_depth = MIN(motion_length, min_contact_depth);
for (int i = 0; i < amount; i++) {
@@ -469,7 +472,7 @@ bool GodotPhysicsDirectSpaceState2D::rest_info(const ShapeParameters &p_paramete
rcd.object = col_obj;
rcd.shape = shape_idx;
rcd.local_shape = 0;
- bool sc = GodotCollisionSolver2D::solve(shape, p_parameters.transform, p_parameters.motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
+ bool sc = GodotCollisionSolver2D::solve(shape, p_parameters.transform, p_parameters.motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, margin);
if (!sc) {
continue;
}
@@ -540,6 +543,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
r_result->collider_id = ObjectID();
r_result->collider_shape = 0;
}
+
Rect2 body_aabb;
bool shapes_found = false;
@@ -565,15 +569,17 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
return false;
}
+ real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE);
+
// Undo the currently transform the physics server is aware of and apply the provided one
body_aabb = p_parameters.from.xform(p_body->get_inv_transform().xform(body_aabb));
- body_aabb = body_aabb.grow(p_parameters.margin);
+ body_aabb = body_aabb.grow(margin);
static const int max_excluded_shape_pairs = 32;
ExcludedShapeSW excluded_shape_pairs[max_excluded_shape_pairs];
int excluded_shape_pair_count = 0;
- real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
+ real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
real_t motion_length = p_parameters.motion.length();
Vector2 motion_normal = p_parameters.motion / motion_length;
@@ -630,7 +636,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
- cbk.valid_depth = MAX(owc_margin, p_parameters.margin); //user specified, but never less than actual margin or it won't work
+ cbk.valid_depth = MAX(owc_margin, margin); //user specified, but never less than actual margin or it won't work
cbk.invalid_by_dir = 0;
if (col_obj->get_type() == GodotCollisionObject2D::TYPE_BODY) {
@@ -655,7 +661,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
bool did_collide = false;
GodotShape2D *against_shape = col_obj->get_shape(shape_idx);
- if (GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, p_parameters.margin)) {
+ if (GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), cbkres, cbkptr, nullptr, margin)) {
did_collide = cbk.passed > current_passed; //more passed, so collision actually existed
}
@@ -927,7 +933,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
real_t owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
- rcd.valid_depth = MAX(owc_margin, p_parameters.margin); //user specified, but never less than actual margin or it won't work
+ rcd.valid_depth = MAX(owc_margin, margin); //user specified, but never less than actual margin or it won't work
if (col_obj->get_type() == GodotCollisionObject2D::TYPE_BODY) {
const GodotBody2D *b = static_cast<const GodotBody2D *>(col_obj);
@@ -949,7 +955,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
rcd.object = col_obj;
rcd.shape = shape_idx;
rcd.local_shape = j;
- bool sc = GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
+ bool sc = GodotCollisionSolver2D::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, margin);
if (!sc) {
continue;
}
@@ -1138,9 +1144,12 @@ void GodotSpace2D::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_v
case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
contact_max_separation = p_value;
break;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
contact_max_allowed_penetration = p_value;
break;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ contact_bias = p_value;
+ break;
case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
body_linear_velocity_sleep_threshold = p_value;
break;
@@ -1153,6 +1162,9 @@ void GodotSpace2D::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_v
case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
constraint_bias = p_value;
break;
+ case PhysicsServer2D::SPACE_PARAM_SOLVER_ITERATIONS:
+ solver_iterations = p_value;
+ break;
}
}
@@ -1162,8 +1174,10 @@ real_t GodotSpace2D::get_param(PhysicsServer2D::SpaceParameter p_param) const {
return contact_recycle_radius;
case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
return contact_max_separation;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
return contact_max_allowed_penetration;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ return contact_bias;
case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
return body_linear_velocity_sleep_threshold;
case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
@@ -1172,6 +1186,8 @@ real_t GodotSpace2D::get_param(PhysicsServer2D::SpaceParameter p_param) const {
return body_time_to_sleep;
case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
return constraint_bias;
+ case PhysicsServer2D::SPACE_PARAM_SOLVER_ITERATIONS:
+ return solver_iterations;
}
return 0;
}
@@ -1198,6 +1214,24 @@ GodotSpace2D::GodotSpace2D() {
body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5);
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/2d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
+ solver_iterations = GLOBAL_DEF("physics/2d/solver/solver_iterations", 16);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/solver_iterations", PropertyInfo(Variant::INT, "physics/2d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater"));
+
+ contact_recycle_radius = GLOBAL_DEF("physics/2d/solver/contact_recycle_radius", 1.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"));
+
+ contact_max_separation = GLOBAL_DEF("physics/2d/solver/contact_max_separation", 1.5);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_max_separation", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"));
+
+ contact_max_allowed_penetration = GLOBAL_DEF("physics/2d/solver/contact_max_allowed_penetration", 0.3);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/contact_max_allowed_penetration", PropertyInfo(Variant::FLOAT, "physics/2d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater"));
+
+ contact_bias = GLOBAL_DEF("physics/2d/solver/default_contact_bias", 0.8);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/default_contact_bias", PropertyInfo(Variant::FLOAT, "physics/2d/solver/default_contact_bias", PROPERTY_HINT_RANGE, "0,1,0.01"));
+
+ constraint_bias = GLOBAL_DEF("physics/2d/solver/default_constraint_bias", 0.2);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/solver/default_constraint_bias", PropertyInfo(Variant::FLOAT, "physics/2d/solver/default_constraint_bias", PROPERTY_HINT_RANGE, "0,1,0.01"));
+
broadphase = GodotBroadPhase2D::create_func();
broadphase->set_pair_callback(_broadphase_pair, this);
broadphase->set_unpair_callback(_broadphase_unpair, this);
diff --git a/servers/physics_2d/godot_space_2d.h b/servers/physics_2d/godot_space_2d.h
index b155a834b6..5d97721176 100644
--- a/servers/physics_2d/godot_space_2d.h
+++ b/servers/physics_2d/godot_space_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -82,7 +82,7 @@ private:
GodotPhysicsDirectSpaceState2D *direct_access = nullptr;
RID self;
- GodotBroadPhase2D *broadphase;
+ GodotBroadPhase2D *broadphase = nullptr;
SelfList<GodotBody2D>::List active_list;
SelfList<GodotBody2D>::List mass_properties_update_list;
SelfList<GodotBody2D>::List state_query_list;
@@ -96,10 +96,13 @@ private:
GodotArea2D *area = nullptr;
- real_t contact_recycle_radius = 1.0;
- real_t contact_max_separation = 1.5;
- real_t contact_max_allowed_penetration = 0.3;
- real_t constraint_bias = 0.2;
+ int solver_iterations = 0;
+
+ real_t contact_recycle_radius = 0.0;
+ real_t contact_max_separation = 0.0;
+ real_t contact_max_allowed_penetration = 0.0;
+ real_t contact_bias = 0.0;
+ real_t constraint_bias = 0.0;
enum {
INTERSECTION_QUERY_MAX = 2048
@@ -155,9 +158,11 @@ public:
void remove_object(GodotCollisionObject2D *p_object);
const Set<GodotCollisionObject2D *> &get_objects() const;
+ _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
+ _FORCE_INLINE_ real_t get_contact_bias() const { return contact_bias; }
_FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
_FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp
index 00d11acdab..866c415440 100644
--- a/servers/physics_2d/godot_step_2d.cpp
+++ b/servers/physics_2d/godot_step_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -124,14 +124,14 @@ void GodotStep2D::_check_suspend(LocalVector<GodotBody2D *> &p_body_island) cons
}
}
-void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta, int p_iterations) {
+void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) {
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
p_space->set_last_step(p_delta);
- iterations = p_iterations;
+ iterations = p_space->get_solver_iterations();
delta = p_delta;
const SelfList<GodotBody2D>::List *body_list = &p_space->get_active_body_list();
diff --git a/servers/physics_2d/godot_step_2d.h b/servers/physics_2d/godot_step_2d.h
index efec243632..9a6d8caf9b 100644
--- a/servers/physics_2d/godot_step_2d.h
+++ b/servers/physics_2d/godot_step_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,7 +55,7 @@ class GodotStep2D {
void _check_suspend(LocalVector<GodotBody2D *> &p_body_island) const;
public:
- void step(GodotSpace2D *p_space, real_t p_delta, int p_iterations);
+ void step(GodotSpace2D *p_space, real_t p_delta);
GodotStep2D();
~GodotStep2D();
};
diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp
index ef6535a878..928ffe0980 100644
--- a/servers/physics_3d/gjk_epa.cpp
+++ b/servers/physics_3d/gjk_epa.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/gjk_epa.h b/servers/physics_3d/gjk_epa.h
index 39a7d03435..01a47f222e 100644
--- a/servers/physics_3d/gjk_epa.h
+++ b/servers/physics_3d/gjk_epa.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_area_3d.cpp b/servers/physics_3d/godot_area_3d.cpp
index d4e14b8d85..e7df23d0d8 100644
--- a/servers/physics_3d/godot_area_3d.cpp
+++ b/servers/physics_3d/godot_area_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_area_3d.h b/servers/physics_3d/godot_area_3d.h
index 0dcf89b2b4..ce64fc802a 100644
--- a/servers/physics_3d/godot_area_3d.h
+++ b/servers/physics_3d/godot_area_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_area_pair_3d.cpp b/servers/physics_3d/godot_area_pair_3d.cpp
index 58188565e3..a75cb74f60 100644
--- a/servers/physics_3d/godot_area_pair_3d.cpp
+++ b/servers/physics_3d/godot_area_pair_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_area_pair_3d.h b/servers/physics_3d/godot_area_pair_3d.h
index 4237e7722e..c416477204 100644
--- a/servers/physics_3d/godot_area_pair_3d.h
+++ b/servers/physics_3d/godot_area_pair_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_body_3d.cpp b/servers/physics_3d/godot_body_3d.cpp
index d5098a2a5f..ad97533f44 100644
--- a/servers/physics_3d/godot_body_3d.cpp
+++ b/servers/physics_3d/godot_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -628,9 +628,8 @@ void GodotBody3D::integrate_forces(real_t p_step) {
if (!omit_force_integration) {
//overridden by direct state query
- Vector3 force = gravity * mass;
- force += applied_force;
- Vector3 torque = applied_torque;
+ Vector3 force = gravity * mass + applied_force + constant_force;
+ Vector3 torque = applied_torque + constant_torque;
real_t damp = 1.0 - p_step * total_linear_damp;
diff --git a/servers/physics_3d/godot_body_3d.h b/servers/physics_3d/godot_body_3d.h
index 6ea6d1fcaa..1906e8aab1 100644
--- a/servers/physics_3d/godot_body_3d.h
+++ b/servers/physics_3d/godot_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -93,6 +93,9 @@ class GodotBody3D : public GodotCollisionObject3D {
Vector3 applied_force;
Vector3 applied_torque;
+ Vector3 constant_force;
+ Vector3 constant_torque;
+
SelfList<GodotBody3D> active_list;
SelfList<GodotBody3D> mass_properties_update_list;
SelfList<GodotBody3D> direct_state_query_list;
@@ -244,19 +247,38 @@ public:
biased_angular_velocity += _inv_inertia_tensor.xform(p_impulse);
}
- _FORCE_INLINE_ void add_central_force(const Vector3 &p_force) {
+ _FORCE_INLINE_ void apply_central_force(const Vector3 &p_force) {
applied_force += p_force;
}
- _FORCE_INLINE_ void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) {
+ _FORCE_INLINE_ void apply_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) {
applied_force += p_force;
applied_torque += (p_position - center_of_mass).cross(p_force);
}
- _FORCE_INLINE_ void add_torque(const Vector3 &p_torque) {
+ _FORCE_INLINE_ void apply_torque(const Vector3 &p_torque) {
applied_torque += p_torque;
}
+ _FORCE_INLINE_ void add_constant_central_force(const Vector3 &p_force) {
+ constant_force += p_force;
+ }
+
+ _FORCE_INLINE_ void add_constant_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) {
+ constant_force += p_force;
+ constant_torque += (p_position - center_of_mass).cross(p_force);
+ }
+
+ _FORCE_INLINE_ void add_constant_torque(const Vector3 &p_torque) {
+ constant_torque += p_torque;
+ }
+
+ void set_constant_force(const Vector3 &p_force) { constant_force = p_force; }
+ Vector3 get_constant_force() const { return constant_force; }
+
+ void set_constant_torque(const Vector3 &p_torque) { constant_torque = p_torque; }
+ Vector3 get_constant_torque() const { return constant_torque; }
+
void set_active(bool p_active);
_FORCE_INLINE_ bool is_active() const { return active; }
@@ -276,12 +298,6 @@ public:
void set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant);
Variant get_state(PhysicsServer3D::BodyState p_state) const;
- void set_applied_force(const Vector3 &p_force) { applied_force = p_force; }
- Vector3 get_applied_force() const { return applied_force; }
-
- void set_applied_torque(const Vector3 &p_torque) { applied_torque = p_torque; }
- Vector3 get_applied_torque() const { return applied_torque; }
-
_FORCE_INLINE_ void set_continuous_collision_detection(bool p_enable) { continuous_cd = p_enable; }
_FORCE_INLINE_ bool is_continuous_collision_detection_enabled() const { return continuous_cd; }
diff --git a/servers/physics_3d/godot_body_direct_state_3d.cpp b/servers/physics_3d/godot_body_direct_state_3d.cpp
index a929cab6f9..a8c6086e1c 100644
--- a/servers/physics_3d/godot_body_direct_state_3d.cpp
+++ b/servers/physics_3d/godot_body_direct_state_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -99,34 +99,71 @@ Vector3 GodotPhysicsDirectBodyState3D::get_velocity_at_local_position(const Vect
return body->get_velocity_in_local_point(p_position);
}
-void GodotPhysicsDirectBodyState3D::add_central_force(const Vector3 &p_force) {
+void GodotPhysicsDirectBodyState3D::apply_central_impulse(const Vector3 &p_impulse) {
body->wakeup();
- body->add_central_force(p_force);
+ body->apply_central_impulse(p_impulse);
}
-void GodotPhysicsDirectBodyState3D::add_force(const Vector3 &p_force, const Vector3 &p_position) {
+void GodotPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
body->wakeup();
- body->add_force(p_force, p_position);
+ body->apply_impulse(p_impulse, p_position);
}
-void GodotPhysicsDirectBodyState3D::add_torque(const Vector3 &p_torque) {
+void GodotPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impulse) {
body->wakeup();
- body->add_torque(p_torque);
+ body->apply_torque_impulse(p_impulse);
}
-void GodotPhysicsDirectBodyState3D::apply_central_impulse(const Vector3 &p_impulse) {
+void GodotPhysicsDirectBodyState3D::apply_central_force(const Vector3 &p_force) {
body->wakeup();
- body->apply_central_impulse(p_impulse);
+ body->apply_central_force(p_force);
}
-void GodotPhysicsDirectBodyState3D::apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position) {
+void GodotPhysicsDirectBodyState3D::apply_force(const Vector3 &p_force, const Vector3 &p_position) {
body->wakeup();
- body->apply_impulse(p_impulse, p_position);
+ body->apply_force(p_force, p_position);
}
-void GodotPhysicsDirectBodyState3D::apply_torque_impulse(const Vector3 &p_impulse) {
+void GodotPhysicsDirectBodyState3D::apply_torque(const Vector3 &p_torque) {
body->wakeup();
- body->apply_torque_impulse(p_impulse);
+ body->apply_torque(p_torque);
+}
+
+void GodotPhysicsDirectBodyState3D::add_constant_central_force(const Vector3 &p_force) {
+ body->wakeup();
+ body->add_constant_central_force(p_force);
+}
+
+void GodotPhysicsDirectBodyState3D::add_constant_force(const Vector3 &p_force, const Vector3 &p_position) {
+ body->wakeup();
+ body->add_constant_force(p_force, p_position);
+}
+
+void GodotPhysicsDirectBodyState3D::add_constant_torque(const Vector3 &p_torque) {
+ body->wakeup();
+ body->add_constant_torque(p_torque);
+}
+
+void GodotPhysicsDirectBodyState3D::set_constant_force(const Vector3 &p_force) {
+ if (!p_force.is_equal_approx(Vector3())) {
+ body->wakeup();
+ }
+ body->set_constant_force(p_force);
+}
+
+Vector3 GodotPhysicsDirectBodyState3D::get_constant_force() const {
+ return body->get_constant_force();
+}
+
+void GodotPhysicsDirectBodyState3D::set_constant_torque(const Vector3 &p_torque) {
+ if (!p_torque.is_equal_approx(Vector3())) {
+ body->wakeup();
+ }
+ body->set_constant_torque(p_torque);
+}
+
+Vector3 GodotPhysicsDirectBodyState3D::get_constant_torque() const {
+ return body->get_constant_torque();
}
void GodotPhysicsDirectBodyState3D::set_sleep_state(bool p_sleep) {
diff --git a/servers/physics_3d/godot_body_direct_state_3d.h b/servers/physics_3d/godot_body_direct_state_3d.h
index 35fd1543b0..483cfb9298 100644
--- a/servers/physics_3d/godot_body_direct_state_3d.h
+++ b/servers/physics_3d/godot_body_direct_state_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,13 +64,24 @@ public:
virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const override;
- virtual void add_central_force(const Vector3 &p_force) override;
- virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override;
- virtual void add_torque(const Vector3 &p_torque) override;
virtual void apply_central_impulse(const Vector3 &p_impulse) override;
virtual void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override;
virtual void apply_torque_impulse(const Vector3 &p_impulse) override;
+ virtual void apply_central_force(const Vector3 &p_force) override;
+ virtual void apply_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override;
+ virtual void apply_torque(const Vector3 &p_torque) override;
+
+ virtual void add_constant_central_force(const Vector3 &p_force) override;
+ virtual void add_constant_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) override;
+ virtual void add_constant_torque(const Vector3 &p_torque) override;
+
+ virtual void set_constant_force(const Vector3 &p_force) override;
+ virtual Vector3 get_constant_force() const override;
+
+ virtual void set_constant_torque(const Vector3 &p_torque) override;
+ virtual Vector3 get_constant_torque() const override;
+
virtual void set_sleep_state(bool p_sleep) override;
virtual bool is_sleeping() const override;
diff --git a/servers/physics_3d/godot_body_pair_3d.cpp b/servers/physics_3d/godot_body_pair_3d.cpp
index 8a701466ed..89d5d59161 100644
--- a/servers/physics_3d/godot_body_pair_3d.cpp
+++ b/servers/physics_3d/godot_body_pair_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,11 +44,6 @@ void GodotBodyPair3D::_contact_added_callback(const Vector3 &p_point_A, int p_in
}
void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_index_A, const Vector3 &p_point_B, int p_index_B) {
- // check if we already have the contact
-
- //Vector3 local_A = A->get_inv_transform().xform(p_point_A);
- //Vector3 local_B = B->get_inv_transform().xform(p_point_B);
-
Vector3 local_A = A->get_inv_transform().basis.xform(p_point_A);
Vector3 local_B = B->get_inv_transform().basis.xform(p_point_B - offset_B);
@@ -57,19 +52,14 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
ERR_FAIL_COND(new_index >= (MAX_CONTACTS + 1));
Contact contact;
-
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_bias_impulse_center_of_mass = 0;
- contact.acc_tangent_impulse = Vector3();
contact.index_A = p_index_A;
contact.index_B = p_index_B;
contact.local_A = local_A;
contact.local_B = local_B;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0; // will be computed in setup()
+ contact.used = true;
- // attempt to determine if the contact will be reused
+ // Attempt to determine if the contact will be reused.
real_t contact_recycle_radius = space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
@@ -80,23 +70,34 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
contact.acc_bias_impulse = c.acc_bias_impulse;
contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass;
contact.acc_tangent_impulse = c.acc_tangent_impulse;
- new_index = i;
- break;
+ c = contact;
+ return;
}
}
- // figure out if the contact amount must be reduced to fit the new contact
-
+ // Figure out if the contact amount must be reduced to fit the new contact.
if (new_index == MAX_CONTACTS) {
- // remove the contact with the minimum depth
+ // Remove the contact with the minimum depth.
+
+ const Basis &basis_A = A->get_transform().basis;
+ const Basis &basis_B = B->get_transform().basis;
int least_deep = -1;
- real_t min_depth = 1e10;
+ real_t min_depth;
- for (int i = 0; i <= contact_count; i++) {
- Contact &c = (i == contact_count) ? contact : contacts[i];
- Vector3 global_A = A->get_transform().basis.xform(c.local_A);
- Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B;
+ // Start with depth for new contact.
+ {
+ Vector3 global_A = basis_A.xform(contact.local_A);
+ Vector3 global_B = basis_B.xform(contact.local_B) + offset_B;
+
+ Vector3 axis = global_A - global_B;
+ min_depth = axis.dot(contact.normal);
+ }
+
+ for (int i = 0; i < contact_count; i++) {
+ const Contact &c = contacts[i];
+ Vector3 global_A = basis_A.xform(c.local_A);
+ Vector3 global_B = basis_B.xform(c.local_B) + offset_B;
Vector3 axis = global_A - global_B;
real_t depth = axis.dot(c.normal);
@@ -107,10 +108,8 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
}
}
- ERR_FAIL_COND(least_deep == -1);
-
- if (least_deep < contact_count) { //replace the last deep contact by the new one
-
+ if (least_deep > -1) {
+ // Replace the least deep contact by the new one.
contacts[least_deep] = contact;
}
@@ -118,29 +117,41 @@ void GodotBodyPair3D::contact_added_callback(const Vector3 &p_point_A, int p_ind
}
contacts[new_index] = contact;
-
- if (new_index == contact_count) {
- contact_count++;
- }
+ contact_count++;
}
void GodotBodyPair3D::validate_contacts() {
- //make sure to erase contacts that are no longer valid
+ // Make sure to erase contacts that are no longer valid.
+ real_t max_separation = space->get_contact_max_separation();
+ real_t max_separation2 = max_separation * max_separation;
+
+ const Basis &basis_A = A->get_transform().basis;
+ const Basis &basis_B = B->get_transform().basis;
- real_t contact_max_separation = space->get_contact_max_separation();
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- Vector3 global_A = A->get_transform().basis.xform(c.local_A);
- Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B;
- Vector3 axis = global_A - global_B;
- real_t depth = axis.dot(c.normal);
+ bool erase = false;
+ if (!c.used) {
+ // Was left behind in previous frame.
+ erase = true;
+ } else {
+ c.used = false;
+
+ Vector3 global_A = basis_A.xform(c.local_A);
+ Vector3 global_B = basis_B.xform(c.local_B) + offset_B;
+ Vector3 axis = global_A - global_B;
+ real_t depth = axis.dot(c.normal);
- if (depth < -contact_max_separation || (global_B + c.normal * depth - global_A).length() > contact_max_separation) {
- // contact no longer needed, remove
+ if (depth < -max_separation || (global_B + c.normal * depth - global_A).length_squared() > max_separation2) {
+ erase = true;
+ }
+ }
+ if (erase) {
+ // Contact no longer needed, remove.
if ((i + 1) < contact_count) {
- // swap with the last one
+ // Swap with the last one.
SWAP(contacts[i], contacts[contact_count - 1]);
}
@@ -161,21 +172,26 @@ bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A,
real_t min, max;
p_A->get_shape(p_shape_A)->project_range(mnormal, p_xform_A, min, max);
- bool fast_object = mlen > (max - min) * 0.3; //going too fast in that direction
- if (!fast_object) { //did it move enough in this direction to even attempt raycast? let's say it should move more than 1/3 the size of the object in that axis
+ // Did it move enough in this direction to even attempt raycast?
+ // Let's say it should move more than 1/3 the size of the object in that axis.
+ bool fast_object = mlen > (max - min) * 0.3;
+ if (!fast_object) {
return false;
}
- //cast a segment from support in motion normal, in the same direction of motion by motion length
- //support is the worst case collision point, so real collision happened before
+ // Going too fast in that direction.
+
+ // Cast a segment from support in motion normal, in the same direction of motion by motion length.
+ // Support is the worst case collision point, so real collision happened before.
Vector3 s = p_A->get_shape(p_shape_A)->get_support(p_xform_A.basis.xform(mnormal).normalized());
Vector3 from = p_xform_A.xform(s);
Vector3 to = from + motion;
Transform3D from_inv = p_xform_B.affine_inverse();
- Vector3 local_from = from_inv.xform(from - mnormal * mlen * 0.1); //start from a little inside the bounding box
+ // Start from a little inside the bounding box.
+ Vector3 local_from = from_inv.xform(from - mnormal * mlen * 0.1);
Vector3 local_to = from_inv.xform(to);
Vector3 rpos, rnorm;
@@ -183,7 +199,8 @@ bool GodotBodyPair3D::_test_ccd(real_t p_step, GodotBody3D *p_A, int p_shape_A,
return false;
}
- //shorten the linear velocity so it does not hit, but gets close enough, next frame will hit softly or soft enough
+ // Shorten the linear velocity so it does not hit, but gets close enough,
+ // next frame will hit softly or soft enough.
Vector3 hitpos = p_xform_B.xform(rpos);
real_t newlen = hitpos.distance_to(from) - (max - min) * 0.01;
@@ -201,6 +218,8 @@ real_t combine_friction(GodotBody3D *A, GodotBody3D *B) {
}
bool GodotBodyPair3D::setup(real_t p_step) {
+ check_ccd = false;
+
if (!A->interacts_with(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self())) {
collided = false;
return false;
@@ -237,14 +256,14 @@ bool GodotBodyPair3D::setup(real_t p_step) {
collided = GodotCollisionSolver3D::solve_static(shape_A_ptr, xform_A, shape_B_ptr, xform_B, _contact_added_callback, this, &sep_axis);
if (!collided) {
- //test ccd (currently just a raycast)
-
if (A->is_continuous_collision_detection_enabled() && collide_A) {
- _test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B);
+ check_ccd = true;
+ return true;
}
if (B->is_continuous_collision_detection_enabled() && collide_B) {
- _test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A);
+ check_ccd = true;
+ return true;
}
return false;
@@ -255,12 +274,30 @@ bool GodotBodyPair3D::setup(real_t p_step) {
bool GodotBodyPair3D::pre_solve(real_t p_step) {
if (!collided) {
+ if (check_ccd) {
+ const Vector3 &offset_A = A->get_transform().get_origin();
+ Transform3D xform_Au = Transform3D(A->get_transform().basis, Vector3());
+ Transform3D xform_A = xform_Au * A->get_shape_transform(shape_A);
+
+ Transform3D xform_Bu = B->get_transform();
+ xform_Bu.origin -= offset_A;
+ Transform3D xform_B = xform_Bu * B->get_shape_transform(shape_B);
+
+ if (A->is_continuous_collision_detection_enabled() && collide_A) {
+ _test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B);
+ }
+
+ if (B->is_continuous_collision_detection_enabled() && collide_B) {
+ _test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A);
+ }
+ }
+
return false;
}
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = (real_t)0.3;
+ real_t bias = 0.8;
GodotShape3D *shape_A_ptr = A->get_shape(shape_A);
GodotShape3D *shape_B_ptr = B->get_shape(shape_B);
@@ -353,8 +390,6 @@ bool GodotBodyPair3D::pre_solve(real_t p_step) {
if (collide_B) {
B->apply_impulse(j_vec, c.rB + B->get_center_of_mass());
}
- c.acc_bias_impulse = 0;
- c.acc_bias_impulse_center_of_mass = 0;
c.bounce = combine_bounce(A, B);
if (c.bounce) {
@@ -538,14 +573,10 @@ void GodotBodySoftBodyPair3D::contact_added_callback(const Vector3 &p_point_A, i
Contact contact;
contact.index_A = p_index_A;
contact.index_B = p_index_B;
- contact.acc_normal_impulse = 0;
- contact.acc_bias_impulse = 0;
- contact.acc_bias_impulse_center_of_mass = 0;
- contact.acc_tangent_impulse = Vector3();
contact.local_A = local_A;
contact.local_B = local_B;
contact.normal = (p_point_A - p_point_B).normalized();
- contact.mass_normal = 0;
+ contact.used = true;
// Attempt to determine if the contact will be reused.
real_t contact_recycle_radius = space->get_contact_recycle_radius();
@@ -571,20 +602,33 @@ void GodotBodySoftBodyPair3D::contact_added_callback(const Vector3 &p_point_A, i
void GodotBodySoftBodyPair3D::validate_contacts() {
// Make sure to erase contacts that are no longer valid.
- const Transform3D &transform_A = body->get_transform();
+ real_t max_separation = space->get_contact_max_separation();
+ real_t max_separation2 = max_separation * max_separation;
- real_t contact_max_separation = space->get_contact_max_separation();
+ const Transform3D &transform_A = body->get_transform();
uint32_t contact_count = contacts.size();
for (uint32_t contact_index = 0; contact_index < contact_count; ++contact_index) {
Contact &c = contacts[contact_index];
- Vector3 global_A = transform_A.xform(c.local_A);
- Vector3 global_B = soft_body->get_node_position(c.index_B) + c.local_B;
- Vector3 axis = global_A - global_B;
- real_t depth = axis.dot(c.normal);
+ bool erase = false;
+ if (!c.used) {
+ // Was left behind in previous frame.
+ erase = true;
+ } else {
+ c.used = false;
+
+ Vector3 global_A = transform_A.xform(c.local_A);
+ Vector3 global_B = soft_body->get_node_position(c.index_B) + c.local_B;
+ Vector3 axis = global_A - global_B;
+ real_t depth = axis.dot(c.normal);
+
+ if (depth < -max_separation || (global_B + c.normal * depth - global_A).length_squared() > max_separation2) {
+ erase = true;
+ }
+ }
- if (depth < -contact_max_separation || (global_B + c.normal * depth - global_A).length() > contact_max_separation) {
+ if (erase) {
// Contact no longer needed, remove.
if ((contact_index + 1) < contact_count) {
// Swap with the last one.
@@ -640,7 +684,7 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) {
real_t max_penetration = space->get_contact_max_allowed_penetration();
- real_t bias = (real_t)0.3;
+ real_t bias = space->get_contact_bias();
GodotShape3D *shape_A_ptr = body->get_shape(body_shape);
@@ -723,8 +767,6 @@ bool GodotBodySoftBodyPair3D::pre_solve(real_t p_step) {
if (soft_body_collides) {
soft_body->apply_node_impulse(c.index_B, j_vec);
}
- c.acc_bias_impulse = 0;
- c.acc_bias_impulse_center_of_mass = 0;
c.bounce = body->get_bounce();
diff --git a/servers/physics_3d/godot_body_pair_3d.h b/servers/physics_3d/godot_body_pair_3d.h
index c0a2424e05..7a7309f9d5 100644
--- a/servers/physics_3d/godot_body_pair_3d.h
+++ b/servers/physics_3d/godot_body_pair_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,11 +54,13 @@ protected:
real_t depth = 0.0;
bool active = false;
+ bool used = false;
Vector3 rA, rB; // Offset in world orientation with respect to center of mass
};
Vector3 sep_axis;
bool collided = false;
+ bool check_ccd = false;
GodotSpace3D *space = nullptr;
diff --git a/servers/physics_3d/godot_broad_phase_3d.cpp b/servers/physics_3d/godot_broad_phase_3d.cpp
index db51dfb2b6..115a01a0c5 100644
--- a/servers/physics_3d/godot_broad_phase_3d.cpp
+++ b/servers/physics_3d/godot_broad_phase_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_broad_phase_3d.h b/servers/physics_3d/godot_broad_phase_3d.h
index 65423f293c..75196cbd1b 100644
--- a/servers/physics_3d/godot_broad_phase_3d.h
+++ b/servers/physics_3d/godot_broad_phase_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp
index 0f2061a1ea..9a6b96c411 100644
--- a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp
+++ b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.h b/servers/physics_3d/godot_broad_phase_3d_bvh.h
index 61127e52c1..7138019a9c 100644
--- a/servers/physics_3d/godot_broad_phase_3d_bvh.h
+++ b/servers/physics_3d/godot_broad_phase_3d_bvh.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_collision_object_3d.cpp b/servers/physics_3d/godot_collision_object_3d.cpp
index 421291011b..63284aeca5 100644
--- a/servers/physics_3d/godot_collision_object_3d.cpp
+++ b/servers/physics_3d/godot_collision_object_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_collision_object_3d.h b/servers/physics_3d/godot_collision_object_3d.h
index 43558034e0..0178838a25 100644
--- a/servers/physics_3d/godot_collision_object_3d.h
+++ b/servers/physics_3d/godot_collision_object_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_collision_solver_3d.cpp b/servers/physics_3d/godot_collision_solver_3d.cpp
index 540b16c6e3..81e1a88366 100644
--- a/servers/physics_3d/godot_collision_solver_3d.cpp
+++ b/servers/physics_3d/godot_collision_solver_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_collision_solver_3d.h b/servers/physics_3d/godot_collision_solver_3d.h
index 133635ca7e..a6a0ebfead 100644
--- a/servers/physics_3d/godot_collision_solver_3d.h
+++ b/servers/physics_3d/godot_collision_solver_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/servers/physics_3d/godot_collision_solver_3d_sat.cpp
index 4faa07b6c9..82e04a7e31 100644
--- a/servers/physics_3d/godot_collision_solver_3d_sat.cpp
+++ b/servers/physics_3d/godot_collision_solver_3d_sat.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.h b/servers/physics_3d/godot_collision_solver_3d_sat.h
index 069a701cba..3eb7aa4c9e 100644
--- a/servers/physics_3d/godot_collision_solver_3d_sat.h
+++ b/servers/physics_3d/godot_collision_solver_3d_sat.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_constraint_3d.h b/servers/physics_3d/godot_constraint_3d.h
index 840c81716c..217955047f 100644
--- a/servers/physics_3d/godot_constraint_3d.h
+++ b/servers/physics_3d/godot_constraint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_joint_3d.h b/servers/physics_3d/godot_joint_3d.h
index 4086bb53e1..d4b719fc5e 100644
--- a/servers/physics_3d/godot_joint_3d.h
+++ b/servers/physics_3d/godot_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp
index 9acae62382..4e1680e6ac 100644
--- a/servers/physics_3d/godot_physics_server_3d.cpp
+++ b/servers/physics_3d/godot_physics_server_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -607,40 +607,40 @@ void GodotPhysicsServer3D::body_attach_object_instance_id(RID p_body, ObjectID p
}
ERR_FAIL_MSG("Invalid ID.");
-};
+}
ObjectID GodotPhysicsServer3D::body_get_object_instance_id(RID p_body) const {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, ObjectID());
return body->get_instance_id();
-};
+}
void GodotPhysicsServer3D::body_set_user_flags(RID p_body, uint32_t p_flags) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
-};
+}
uint32_t GodotPhysicsServer3D::body_get_user_flags(RID p_body) const {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, 0);
return 0;
-};
+}
void GodotPhysicsServer3D::body_set_param(RID p_body, BodyParameter p_param, const Variant &p_value) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
body->set_param(p_param, p_value);
-};
+}
Variant GodotPhysicsServer3D::body_get_param(RID p_body, BodyParameter p_param) const {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->get_param(p_param);
-};
+}
void GodotPhysicsServer3D::body_reset_mass_properties(RID p_body) {
GodotBody3D *body = body_owner.get_or_null(p_body);
@@ -654,97 +654,125 @@ void GodotPhysicsServer3D::body_set_state(RID p_body, BodyState p_state, const V
ERR_FAIL_COND(!body);
body->set_state(p_state, p_variant);
-};
+}
Variant GodotPhysicsServer3D::body_get_state(RID p_body, BodyState p_state) const {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND_V(!body, Variant());
return body->get_state(p_state);
-};
+}
-void GodotPhysicsServer3D::body_set_applied_force(RID p_body, const Vector3 &p_force) {
+void GodotPhysicsServer3D::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->set_applied_force(p_force);
+ _update_shapes();
+
+ body->apply_central_impulse(p_impulse);
body->wakeup();
-};
+}
-Vector3 GodotPhysicsServer3D::body_get_applied_force(RID p_body) const {
+void GodotPhysicsServer3D::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) {
GodotBody3D *body = body_owner.get_or_null(p_body);
- ERR_FAIL_COND_V(!body, Vector3());
- return body->get_applied_force();
-};
+ ERR_FAIL_COND(!body);
+
+ _update_shapes();
+
+ body->apply_impulse(p_impulse, p_position);
+ body->wakeup();
+}
-void GodotPhysicsServer3D::body_set_applied_torque(RID p_body, const Vector3 &p_torque) {
+void GodotPhysicsServer3D::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->set_applied_torque(p_torque);
+ _update_shapes();
+
+ body->apply_torque_impulse(p_impulse);
body->wakeup();
-};
+}
-Vector3 GodotPhysicsServer3D::body_get_applied_torque(RID p_body) const {
+void GodotPhysicsServer3D::body_apply_central_force(RID p_body, const Vector3 &p_force) {
GodotBody3D *body = body_owner.get_or_null(p_body);
- ERR_FAIL_COND_V(!body, Vector3());
+ ERR_FAIL_COND(!body);
- return body->get_applied_torque();
-};
+ body->apply_central_force(p_force);
+ body->wakeup();
+}
-void GodotPhysicsServer3D::body_add_central_force(RID p_body, const Vector3 &p_force) {
+void GodotPhysicsServer3D::body_apply_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->add_central_force(p_force);
+ body->apply_force(p_force, p_position);
body->wakeup();
}
-void GodotPhysicsServer3D::body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) {
+void GodotPhysicsServer3D::body_apply_torque(RID p_body, const Vector3 &p_torque) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->add_force(p_force, p_position);
+ body->apply_torque(p_torque);
body->wakeup();
-};
+}
-void GodotPhysicsServer3D::body_add_torque(RID p_body, const Vector3 &p_torque) {
+void GodotPhysicsServer3D::body_add_constant_central_force(RID p_body, const Vector3 &p_force) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- body->add_torque(p_torque);
+ body->add_constant_central_force(p_force);
body->wakeup();
-};
+}
-void GodotPhysicsServer3D::body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) {
+void GodotPhysicsServer3D::body_add_constant_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- _update_shapes();
+ body->add_constant_force(p_force, p_position);
+ body->wakeup();
+}
- body->apply_central_impulse(p_impulse);
+void GodotPhysicsServer3D::body_add_constant_torque(RID p_body, const Vector3 &p_torque) {
+ GodotBody3D *body = body_owner.get_or_null(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->add_constant_torque(p_torque);
body->wakeup();
}
-void GodotPhysicsServer3D::body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position) {
+void GodotPhysicsServer3D::body_set_constant_force(RID p_body, const Vector3 &p_force) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- _update_shapes();
+ body->set_constant_force(p_force);
+ if (!p_force.is_equal_approx(Vector3())) {
+ body->wakeup();
+ }
+}
- body->apply_impulse(p_impulse, p_position);
- body->wakeup();
-};
+Vector3 GodotPhysicsServer3D::body_get_constant_force(RID p_body) const {
+ GodotBody3D *body = body_owner.get_or_null(p_body);
+ ERR_FAIL_COND_V(!body, Vector3());
+ return body->get_constant_force();
+}
-void GodotPhysicsServer3D::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) {
+void GodotPhysicsServer3D::body_set_constant_torque(RID p_body, const Vector3 &p_torque) {
GodotBody3D *body = body_owner.get_or_null(p_body);
ERR_FAIL_COND(!body);
- _update_shapes();
+ body->set_constant_torque(p_torque);
+ if (!p_torque.is_equal_approx(Vector3())) {
+ body->wakeup();
+ }
+}
- body->apply_torque_impulse(p_impulse);
- body->wakeup();
-};
+Vector3 GodotPhysicsServer3D::body_get_constant_torque(RID p_body) const {
+ GodotBody3D *body = body_owner.get_or_null(p_body);
+ ERR_FAIL_COND_V(!body, Vector3());
+
+ return body->get_constant_torque();
+}
void GodotPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) {
GodotBody3D *body = body_owner.get_or_null(p_body);
@@ -758,7 +786,7 @@ void GodotPhysicsServer3D::body_set_axis_velocity(RID p_body, const Vector3 &p_a
v += p_axis_velocity;
body->set_linear_velocity(v);
body->wakeup();
-};
+}
void GodotPhysicsServer3D::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) {
GodotBody3D *body = body_owner.get_or_null(p_body);
@@ -1574,20 +1602,15 @@ void GodotPhysicsServer3D::free(RID p_rid) {
} else {
ERR_FAIL_MSG("Invalid ID.");
}
-};
+}
void GodotPhysicsServer3D::set_active(bool p_active) {
active = p_active;
-};
-
-void GodotPhysicsServer3D::set_collision_iterations(int p_iterations) {
- iterations = p_iterations;
-};
+}
void GodotPhysicsServer3D::init() {
- iterations = 8; // 8?
stepper = memnew(GodotStep3D);
-};
+}
void GodotPhysicsServer3D::step(real_t p_step) {
#ifndef _3D_DISABLED
@@ -1602,7 +1625,7 @@ void GodotPhysicsServer3D::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step((GodotSpace3D *)E->get(), p_step, iterations);
+ stepper->step((GodotSpace3D *)E->get(), p_step);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
collision_pairs += E->get()->get_collision_pairs();
@@ -1612,7 +1635,7 @@ void GodotPhysicsServer3D::step(real_t p_step) {
void GodotPhysicsServer3D::sync() {
doing_sync = true;
-};
+}
void GodotPhysicsServer3D::flush_queries() {
#ifndef _3D_DISABLED
@@ -1665,15 +1688,15 @@ void GodotPhysicsServer3D::flush_queries() {
EngineDebugger::profiler_add_frame_data("servers", values);
}
#endif
-};
+}
void GodotPhysicsServer3D::end_sync() {
doing_sync = false;
-};
+}
void GodotPhysicsServer3D::finish() {
memdelete(stepper);
-};
+}
int GodotPhysicsServer3D::get_process_info(ProcessInfo p_info) {
switch (p_info) {
diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h
index f5c8e0f60d..b903f4808c 100644
--- a/servers/physics_3d/godot_physics_server_3d.h
+++ b/servers/physics_3d/godot_physics_server_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,6 @@ class GodotPhysicsServer3D : public PhysicsServer3D {
friend class GodotPhysicsDirectSpaceState3D;
bool active = true;
- int iterations = 0;
int island_count = 0;
int active_objects = 0;
@@ -204,19 +203,24 @@ public:
virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) override;
virtual Variant body_get_state(RID p_body, BodyState p_state) const override;
- virtual void body_set_applied_force(RID p_body, const Vector3 &p_force) override;
- virtual Vector3 body_get_applied_force(RID p_body) const override;
-
- virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque) override;
- virtual Vector3 body_get_applied_torque(RID p_body) const override;
-
- virtual void body_add_central_force(RID p_body, const Vector3 &p_force) override;
- virtual void body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override;
- virtual void body_add_torque(RID p_body, const Vector3 &p_torque) override;
-
virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) override;
virtual void body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) override;
virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) override;
+
+ virtual void body_apply_central_force(RID p_body, const Vector3 &p_force) override;
+ virtual void body_apply_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override;
+ virtual void body_apply_torque(RID p_body, const Vector3 &p_torque) override;
+
+ virtual void body_add_constant_central_force(RID p_body, const Vector3 &p_force) override;
+ virtual void body_add_constant_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) override;
+ virtual void body_add_constant_torque(RID p_body, const Vector3 &p_torque) override;
+
+ virtual void body_set_constant_force(RID p_body, const Vector3 &p_force) override;
+ virtual Vector3 body_get_constant_force(RID p_body) const override;
+
+ virtual void body_set_constant_torque(RID p_body, const Vector3 &p_torque) override;
+ virtual Vector3 body_get_constant_torque(RID p_body) const override;
+
virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) override;
virtual void body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) override;
@@ -364,8 +368,6 @@ public:
virtual void end_sync() override;
virtual void finish() override;
- virtual void set_collision_iterations(int p_iterations) override;
-
virtual bool is_flushing_queries() const override { return flushing_queries; }
int get_process_info(ProcessInfo p_info) override;
diff --git a/servers/physics_3d/godot_shape_3d.cpp b/servers/physics_3d/godot_shape_3d.cpp
index 5364a9833d..26fa470233 100644
--- a/servers/physics_3d/godot_shape_3d.cpp
+++ b/servers/physics_3d/godot_shape_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_shape_3d.h b/servers/physics_3d/godot_shape_3d.h
index 43319510d4..9d171c3928 100644
--- a/servers/physics_3d/godot_shape_3d.h
+++ b/servers/physics_3d/godot_shape_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp
index 43d4433302..1de27760d5 100644
--- a/servers/physics_3d/godot_soft_body_3d.cpp
+++ b/servers/physics_3d/godot_soft_body_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_soft_body_3d.h b/servers/physics_3d/godot_soft_body_3d.h
index 14ddc419cf..5028e81dd8 100644
--- a/servers/physics_3d/godot_soft_body_3d.h
+++ b/servers/physics_3d/godot_soft_body_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp
index f503273c88..ed756a7f9d 100644
--- a/servers/physics_3d/godot_space_3d.cpp
+++ b/servers/physics_3d/godot_space_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,6 +35,7 @@
#include "core/config/project_settings.h"
+#define TEST_MOTION_MARGIN_MIN_VALUE 0.0001
#define TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR 0.05
_FORCE_INLINE_ static bool _can_collide_with(GodotCollisionObject3D *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
@@ -507,8 +508,10 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_paramete
GodotShape3D *shape = GodotPhysicsServer3D::godot_singleton->shape_owner.get_or_null(p_parameters.shape_rid);
ERR_FAIL_COND_V(!shape, 0);
+ real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE);
+
AABB aabb = p_parameters.transform.xform(shape->get_aabb());
- aabb = aabb.grow(p_parameters.margin);
+ aabb = aabb.grow(margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, GodotSpace3D::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -516,7 +519,7 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_paramete
// Allowed depth can't be lower than motion length, in order to handle contacts at low speed.
real_t motion_length = p_parameters.motion.length();
- real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
+ real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
rcd.min_allowed_depth = MIN(motion_length, min_contact_depth);
for (int i = 0; i < amount; i++) {
@@ -534,7 +537,7 @@ bool GodotPhysicsDirectSpaceState3D::rest_info(const ShapeParameters &p_paramete
rcd.object = col_obj;
rcd.shape = shape_idx;
- bool sc = GodotCollisionSolver3D::solve_static(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
+ bool sc = GodotCollisionSolver3D::solve_static(shape, p_parameters.transform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, margin);
if (!sc) {
continue;
}
@@ -677,11 +680,13 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::
return false;
}
+ real_t margin = MAX(p_parameters.margin, TEST_MOTION_MARGIN_MIN_VALUE);
+
// Undo the currently transform the physics server is aware of and apply the provided one
body_aabb = p_parameters.from.xform(p_body->get_inv_transform().xform(body_aabb));
- body_aabb = body_aabb.grow(p_parameters.margin);
+ body_aabb = body_aabb.grow(margin);
- real_t min_contact_depth = p_parameters.margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
+ real_t min_contact_depth = margin * TEST_MOTION_MIN_CONTACT_DEPTH_FACTOR;
real_t motion_length = p_parameters.motion.length();
Vector3 motion_normal = p_parameters.motion / motion_length;
@@ -729,7 +734,7 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::
int shape_idx = intersection_query_subindex_results[i];
- if (GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, p_parameters.margin)) {
+ if (GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, nullptr, margin)) {
collided = cbk.amount > 0;
}
}
@@ -949,7 +954,7 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::
rcd.object = col_obj;
rcd.shape = shape_idx;
- bool sc = GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_parameters.margin);
+ bool sc = GodotCollisionSolver3D::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, margin);
if (!sc) {
continue;
}
@@ -1173,9 +1178,12 @@ void GodotSpace3D::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_v
case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
contact_max_separation = p_value;
break;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
contact_max_allowed_penetration = p_value;
break;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ contact_bias = p_value;
+ break;
case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
body_linear_velocity_sleep_threshold = p_value;
break;
@@ -1185,11 +1193,8 @@ void GodotSpace3D::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_v
case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
body_time_to_sleep = p_value;
break;
- case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
- body_angular_velocity_damp_ratio = p_value;
- break;
- case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
- constraint_bias = p_value;
+ case PhysicsServer3D::SPACE_PARAM_SOLVER_ITERATIONS:
+ solver_iterations = p_value;
break;
}
}
@@ -1200,18 +1205,18 @@ real_t GodotSpace3D::get_param(PhysicsServer3D::SpaceParameter p_param) const {
return contact_recycle_radius;
case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
return contact_max_separation;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION:
return contact_max_allowed_penetration;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_DEFAULT_BIAS:
+ return contact_bias;
case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
return body_linear_velocity_sleep_threshold;
case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
return body_angular_velocity_sleep_threshold;
case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
return body_time_to_sleep;
- case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
- return body_angular_velocity_damp_ratio;
- case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
- return constraint_bias;
+ case PhysicsServer3D::SPACE_PARAM_SOLVER_ITERATIONS:
+ return solver_iterations;
}
return 0;
}
@@ -1237,7 +1242,21 @@ GodotSpace3D::GodotSpace3D() {
body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/3d/sleep_threshold_angular", Math::deg2rad(8.0));
body_time_to_sleep = GLOBAL_DEF("physics/3d/time_before_sleep", 0.5);
ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/time_before_sleep", PropertyInfo(Variant::FLOAT, "physics/3d/time_before_sleep", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
- body_angular_velocity_damp_ratio = 10;
+
+ solver_iterations = GLOBAL_DEF("physics/3d/solver/solver_iterations", 16);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/solver_iterations", PropertyInfo(Variant::INT, "physics/3d/solver/solver_iterations", PROPERTY_HINT_RANGE, "1,32,1,or_greater"));
+
+ contact_recycle_radius = GLOBAL_DEF("physics/3d/solver/contact_recycle_radius", 0.01);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_recycle_radius", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"));
+
+ contact_max_separation = GLOBAL_DEF("physics/3d/solver/contact_max_separation", 0.05);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_max_separation", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_separation", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"));
+
+ contact_max_allowed_penetration = GLOBAL_DEF("physics/3d/solver/contact_max_allowed_penetration", 0.01);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/contact_max_allowed_penetration", PropertyInfo(Variant::FLOAT, "physics/3d/solver/contact_max_allowed_penetration", PROPERTY_HINT_RANGE, "0,0.1,0.01,or_greater"));
+
+ contact_bias = GLOBAL_DEF("physics/3d/solver/default_contact_bias", 0.8);
+ ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/solver/default_contact_bias", PropertyInfo(Variant::FLOAT, "physics/3d/solver/default_contact_bias", PROPERTY_HINT_RANGE, "0,1,0.01"));
broadphase = GodotBroadPhase3D::create_func();
broadphase->set_pair_callback(_broadphase_pair, this);
diff --git a/servers/physics_3d/godot_space_3d.h b/servers/physics_3d/godot_space_3d.h
index aa5e965751..ac54c8bf69 100644
--- a/servers/physics_3d/godot_space_3d.h
+++ b/servers/physics_3d/godot_space_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -75,10 +75,10 @@ public:
private:
uint64_t elapsed_time[ELAPSED_TIME_MAX] = {};
- GodotPhysicsDirectSpaceState3D *direct_access;
+ GodotPhysicsDirectSpaceState3D *direct_access = nullptr;
RID self;
- GodotBroadPhase3D *broadphase;
+ GodotBroadPhase3D *broadphase = nullptr;
SelfList<GodotBody3D>::List active_list;
SelfList<GodotBody3D>::List mass_properties_update_list;
SelfList<GodotBody3D>::List state_query_list;
@@ -93,10 +93,12 @@ private:
GodotArea3D *area = nullptr;
- real_t contact_recycle_radius = 0.01;
- real_t contact_max_separation = 0.05;
- real_t contact_max_allowed_penetration = 0.01;
- real_t constraint_bias = 0.01;
+ int solver_iterations = 0;
+
+ real_t contact_recycle_radius = 0.0;
+ real_t contact_max_separation = 0.0;
+ real_t contact_max_allowed_penetration = 0.0;
+ real_t contact_bias = 0.0;
enum {
INTERSECTION_QUERY_MAX = 2048
@@ -105,10 +107,9 @@ private:
GodotCollisionObject3D *intersection_query_results[INTERSECTION_QUERY_MAX];
int intersection_query_subindex_results[INTERSECTION_QUERY_MAX];
- real_t body_linear_velocity_sleep_threshold;
- real_t body_angular_velocity_sleep_threshold;
- real_t body_time_to_sleep;
- real_t body_angular_velocity_damp_ratio;
+ real_t body_linear_velocity_sleep_threshold = 0.0;
+ real_t body_angular_velocity_sleep_threshold = 0.0;
+ real_t body_time_to_sleep = 0.0;
bool locked = false;
@@ -159,14 +160,14 @@ public:
void remove_object(GodotCollisionObject3D *p_object);
const Set<GodotCollisionObject3D *> &get_objects() const;
+ _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
_FORCE_INLINE_ real_t get_contact_max_separation() const { return contact_max_separation; }
_FORCE_INLINE_ real_t get_contact_max_allowed_penetration() const { return contact_max_allowed_penetration; }
- _FORCE_INLINE_ real_t get_constraint_bias() const { return constraint_bias; }
+ _FORCE_INLINE_ real_t get_contact_bias() const { return contact_bias; }
_FORCE_INLINE_ real_t get_body_linear_velocity_sleep_threshold() const { return body_linear_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_angular_velocity_sleep_threshold() const { return body_angular_velocity_sleep_threshold; }
_FORCE_INLINE_ real_t get_body_time_to_sleep() const { return body_time_to_sleep; }
- _FORCE_INLINE_ real_t get_body_angular_velocity_damp_ratio() const { return body_angular_velocity_damp_ratio; }
void update();
void setup();
diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp
index 5453c4415c..63635b224b 100644
--- a/servers/physics_3d/godot_step_3d.cpp
+++ b/servers/physics_3d/godot_step_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -181,14 +181,14 @@ void GodotStep3D::_check_suspend(const LocalVector<GodotBody3D *> &p_body_island
}
}
-void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta, int p_iterations) {
+void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) {
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
p_space->set_last_step(p_delta);
- iterations = p_iterations;
+ iterations = p_space->get_solver_iterations();
delta = p_delta;
const SelfList<GodotBody3D>::List *body_list = &p_space->get_active_body_list();
diff --git a/servers/physics_3d/godot_step_3d.h b/servers/physics_3d/godot_step_3d.h
index 23ede4feff..6d975b0dd3 100644
--- a/servers/physics_3d/godot_step_3d.h
+++ b/servers/physics_3d/godot_step_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -56,7 +56,7 @@ class GodotStep3D {
void _check_suspend(const LocalVector<GodotBody3D *> &p_body_island) const;
public:
- void step(GodotSpace3D *p_space, real_t p_delta, int p_iterations);
+ void step(GodotSpace3D *p_space, real_t p_delta);
GodotStep3D();
~GodotStep3D();
};
diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp b/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp
index 864086c956..dc4858ff9a 100644
--- a/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_cone_twist_joint_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h b/servers/physics_3d/joints/godot_cone_twist_joint_3d.h
index 999d0f0692..fdcc2ceea3 100644
--- a/servers/physics_3d/joints/godot_cone_twist_joint_3d.h
+++ b/servers/physics_3d/joints/godot_cone_twist_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp
index 915bb528e9..41e9bf06bb 100644
--- a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h
index f37b5b981b..bcf2d18647 100644
--- a/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h
+++ b/servers/physics_3d/joints/godot_generic_6dof_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp
index cf77129a30..a7a7843499 100644
--- a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.h b/servers/physics_3d/joints/godot_hinge_joint_3d.h
index ff1fbe0f25..b934540e8d 100644
--- a/servers/physics_3d/joints/godot_hinge_joint_3d.h
+++ b/servers/physics_3d/joints/godot_hinge_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_jacobian_entry_3d.h b/servers/physics_3d/joints/godot_jacobian_entry_3d.h
index 90a77a9b61..0fe15751d5 100644
--- a/servers/physics_3d/joints/godot_jacobian_entry_3d.h
+++ b/servers/physics_3d/joints/godot_jacobian_entry_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_pin_joint_3d.cpp b/servers/physics_3d/joints/godot_pin_joint_3d.cpp
index e9e81b61a7..c52ea2665c 100644
--- a/servers/physics_3d/joints/godot_pin_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_pin_joint_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_pin_joint_3d.h b/servers/physics_3d/joints/godot_pin_joint_3d.h
index 17e2e6e973..eeeaa650bd 100644
--- a/servers/physics_3d/joints/godot_pin_joint_3d.h
+++ b/servers/physics_3d/joints/godot_pin_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.cpp b/servers/physics_3d/joints/godot_slider_joint_3d.cpp
index 1f463ad24c..f175421304 100644
--- a/servers/physics_3d/joints/godot_slider_joint_3d.cpp
+++ b/servers/physics_3d/joints/godot_slider_joint_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_3d/joints/godot_slider_joint_3d.h b/servers/physics_3d/joints/godot_slider_joint_3d.h
index 9baaf1fa40..f596c9ff75 100644
--- a/servers/physics_3d/joints/godot_slider_joint_3d.h
+++ b/servers/physics_3d/joints/godot_slider_joint_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 76f0b74c72..d8f2a2a780 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -93,13 +93,24 @@ void PhysicsDirectBodyState2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_velocity_at_local_position", "local_position"), &PhysicsDirectBodyState2D::get_velocity_at_local_position);
- ClassDB::bind_method(D_METHOD("add_central_force", "force"), &PhysicsDirectBodyState2D::add_central_force);
- ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState2D::add_force, Vector2());
- ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState2D::add_torque);
ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &PhysicsDirectBodyState2D::apply_central_impulse);
ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &PhysicsDirectBodyState2D::apply_torque_impulse);
ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &PhysicsDirectBodyState2D::apply_impulse, Vector2());
+ ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &PhysicsDirectBodyState2D::apply_central_force, Vector2());
+ ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &PhysicsDirectBodyState2D::apply_force, Vector2());
+ ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &PhysicsDirectBodyState2D::apply_torque);
+
+ ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &PhysicsDirectBodyState2D::add_constant_central_force, Vector2());
+ ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &PhysicsDirectBodyState2D::add_constant_force, Vector2());
+ ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &PhysicsDirectBodyState2D::add_constant_torque);
+
+ ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &PhysicsDirectBodyState2D::set_constant_force);
+ ClassDB::bind_method(D_METHOD("get_constant_force"), &PhysicsDirectBodyState2D::get_constant_force);
+
+ ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &PhysicsDirectBodyState2D::set_constant_torque);
+ ClassDB::bind_method(D_METHOD("get_constant_torque"), &PhysicsDirectBodyState2D::get_constant_torque);
+
ClassDB::bind_method(D_METHOD("set_sleep_state", "enabled"), &PhysicsDirectBodyState2D::set_sleep_state);
ClassDB::bind_method(D_METHOD("is_sleeping"), &PhysicsDirectBodyState2D::is_sleeping);
@@ -688,9 +699,21 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_apply_central_impulse", "body", "impulse"), &PhysicsServer2D::body_apply_central_impulse);
ClassDB::bind_method(D_METHOD("body_apply_torque_impulse", "body", "impulse"), &PhysicsServer2D::body_apply_torque_impulse);
ClassDB::bind_method(D_METHOD("body_apply_impulse", "body", "impulse", "position"), &PhysicsServer2D::body_apply_impulse, Vector2());
- ClassDB::bind_method(D_METHOD("body_add_central_force", "body", "force"), &PhysicsServer2D::body_add_central_force);
- ClassDB::bind_method(D_METHOD("body_add_force", "body", "force", "position"), &PhysicsServer2D::body_add_force, Vector2());
- ClassDB::bind_method(D_METHOD("body_add_torque", "body", "torque"), &PhysicsServer2D::body_add_torque);
+
+ ClassDB::bind_method(D_METHOD("body_apply_central_force", "body", "force"), &PhysicsServer2D::body_apply_central_force);
+ ClassDB::bind_method(D_METHOD("body_apply_force", "body", "force", "position"), &PhysicsServer2D::body_apply_force, Vector2());
+ ClassDB::bind_method(D_METHOD("body_apply_torque", "body", "torque"), &PhysicsServer2D::body_apply_torque);
+
+ ClassDB::bind_method(D_METHOD("body_add_constant_central_force", "body", "force"), &PhysicsServer2D::body_add_constant_central_force);
+ ClassDB::bind_method(D_METHOD("body_add_constant_force", "body", "force", "position"), &PhysicsServer2D::body_add_constant_force, Vector2());
+ ClassDB::bind_method(D_METHOD("body_add_constant_torque", "body", "torque"), &PhysicsServer2D::body_add_constant_torque);
+
+ ClassDB::bind_method(D_METHOD("body_set_constant_force", "body", "force"), &PhysicsServer2D::body_set_constant_force);
+ ClassDB::bind_method(D_METHOD("body_get_constant_force", "body"), &PhysicsServer2D::body_get_constant_force);
+
+ ClassDB::bind_method(D_METHOD("body_set_constant_torque", "body", "torque"), &PhysicsServer2D::body_set_constant_torque);
+ ClassDB::bind_method(D_METHOD("body_get_constant_torque", "body"), &PhysicsServer2D::body_get_constant_torque);
+
ClassDB::bind_method(D_METHOD("body_set_axis_velocity", "body", "axis_velocity"), &PhysicsServer2D::body_set_axis_velocity);
ClassDB::bind_method(D_METHOD("body_add_collision_exception", "body", "excepted_body"), &PhysicsServer2D::body_add_collision_exception);
@@ -730,17 +753,17 @@ void PhysicsServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer2D::set_active);
- ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer2D::set_collision_iterations);
-
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer2D::get_process_info);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
- BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_DEFAULT_BIAS);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_SOLVER_ITERATIONS);
BIND_ENUM_CONSTANT(SHAPE_WORLD_BOUNDARY);
BIND_ENUM_CONSTANT(SHAPE_SEPARATION_RAY);
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 2bff8f5dcb..e9faf0a3bf 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -64,13 +64,24 @@ public:
virtual Vector2 get_velocity_at_local_position(const Vector2 &p_position) const = 0;
- virtual void add_central_force(const Vector2 &p_force) = 0;
- virtual void add_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
- virtual void add_torque(real_t p_torque) = 0;
virtual void apply_central_impulse(const Vector2 &p_impulse) = 0;
virtual void apply_torque_impulse(real_t p_torque) = 0;
virtual void apply_impulse(const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) = 0;
+ virtual void apply_central_force(const Vector2 &p_force) = 0;
+ virtual void apply_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
+ virtual void apply_torque(real_t p_torque) = 0;
+
+ virtual void add_constant_central_force(const Vector2 &p_force) = 0;
+ virtual void add_constant_force(const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
+ virtual void add_constant_torque(real_t p_torque) = 0;
+
+ virtual void set_constant_force(const Vector2 &p_force) = 0;
+ virtual Vector2 get_constant_force() const = 0;
+
+ virtual void set_constant_torque(real_t p_torque) = 0;
+ virtual real_t get_constant_torque() const = 0;
+
virtual void set_sleep_state(bool p_enable) = 0;
virtual bool is_sleeping() const = 0;
@@ -242,11 +253,13 @@ public:
enum SpaceParameter {
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
- SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_DEFAULT_BIAS,
SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
+ SPACE_PARAM_SOLVER_ITERATIONS,
};
virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0;
@@ -417,20 +430,24 @@ public:
virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) = 0;
virtual Variant body_get_state(RID p_body, BodyState p_state) const = 0;
- //do something about it
- virtual void body_set_applied_force(RID p_body, const Vector2 &p_force) = 0;
- virtual Vector2 body_get_applied_force(RID p_body) const = 0;
-
- virtual void body_set_applied_torque(RID p_body, real_t p_torque) = 0;
- virtual real_t body_get_applied_torque(RID p_body) const = 0;
-
- virtual void body_add_central_force(RID p_body, const Vector2 &p_force) = 0;
- virtual void body_add_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
- virtual void body_add_torque(RID p_body, real_t p_torque) = 0;
-
virtual void body_apply_central_impulse(RID p_body, const Vector2 &p_impulse) = 0;
virtual void body_apply_torque_impulse(RID p_body, real_t p_torque) = 0;
virtual void body_apply_impulse(RID p_body, const Vector2 &p_impulse, const Vector2 &p_position = Vector2()) = 0;
+
+ virtual void body_apply_central_force(RID p_body, const Vector2 &p_force) = 0;
+ virtual void body_apply_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
+ virtual void body_apply_torque(RID p_body, real_t p_torque) = 0;
+
+ virtual void body_add_constant_central_force(RID p_body, const Vector2 &p_force) = 0;
+ virtual void body_add_constant_force(RID p_body, const Vector2 &p_force, const Vector2 &p_position = Vector2()) = 0;
+ virtual void body_add_constant_torque(RID p_body, real_t p_torque) = 0;
+
+ virtual void body_set_constant_force(RID p_body, const Vector2 &p_force) = 0;
+ virtual Vector2 body_get_constant_force(RID p_body) const = 0;
+
+ virtual void body_set_constant_torque(RID p_body, real_t p_torque) = 0;
+ virtual real_t body_get_constant_torque(RID p_body) const = 0;
+
virtual void body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) = 0;
//fix
@@ -566,8 +583,6 @@ public:
virtual bool is_flushing_queries() const = 0;
- virtual void set_collision_iterations(int p_iterations) = 0;
-
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
INFO_COLLISION_PAIRS,
@@ -758,10 +773,9 @@ class PhysicsServer2DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/physics_server_2d_wrap_mt.cpp b/servers/physics_server_2d_wrap_mt.cpp
index 33070bf42d..02223b83f0 100644
--- a/servers/physics_server_2d_wrap_mt.cpp
+++ b/servers/physics_server_2d_wrap_mt.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_server_2d_wrap_mt.h b/servers/physics_server_2d_wrap_mt.h
index dda4eb6ffa..aa3a8bc04a 100644
--- a/servers/physics_server_2d_wrap_mt.h
+++ b/servers/physics_server_2d_wrap_mt.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -213,18 +213,24 @@ public:
FUNC3(body_set_state, RID, BodyState, const Variant &);
FUNC2RC(Variant, body_get_state, RID, BodyState);
- FUNC2(body_set_applied_force, RID, const Vector2 &);
- FUNC1RC(Vector2, body_get_applied_force, RID);
-
- FUNC2(body_set_applied_torque, RID, real_t);
- FUNC1RC(real_t, body_get_applied_torque, RID);
-
- FUNC2(body_add_central_force, RID, const Vector2 &);
- FUNC3(body_add_force, RID, const Vector2 &, const Vector2 &);
- FUNC2(body_add_torque, RID, real_t);
FUNC2(body_apply_central_impulse, RID, const Vector2 &);
FUNC2(body_apply_torque_impulse, RID, real_t);
FUNC3(body_apply_impulse, RID, const Vector2 &, const Vector2 &);
+
+ FUNC2(body_apply_central_force, RID, const Vector2 &);
+ FUNC3(body_apply_force, RID, const Vector2 &, const Vector2 &);
+ FUNC2(body_apply_torque, RID, real_t);
+
+ FUNC2(body_add_constant_central_force, RID, const Vector2 &);
+ FUNC3(body_add_constant_force, RID, const Vector2 &, const Vector2 &);
+ FUNC2(body_add_constant_torque, RID, real_t);
+
+ FUNC2(body_set_constant_force, RID, const Vector2 &);
+ FUNC1RC(Vector2, body_get_constant_force, RID);
+
+ FUNC2(body_set_constant_torque, RID, real_t);
+ FUNC1RC(real_t, body_get_constant_torque, RID);
+
FUNC2(body_set_axis_velocity, RID, const Vector2 &);
FUNC2(body_add_collision_exception, RID, RID);
@@ -294,7 +300,6 @@ public:
FUNC1(free, RID);
FUNC1(set_active, bool);
- FUNC1(set_collision_iterations, int);
virtual void init() override;
virtual void step(real_t p_step) override;
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 373f216e01..8fafd07f87 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -94,13 +94,24 @@ void PhysicsDirectBodyState3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_velocity_at_local_position", "local_position"), &PhysicsDirectBodyState3D::get_velocity_at_local_position);
- ClassDB::bind_method(D_METHOD("add_central_force", "force"), &PhysicsDirectBodyState3D::add_central_force, Vector3());
- ClassDB::bind_method(D_METHOD("add_force", "force", "position"), &PhysicsDirectBodyState3D::add_force, Vector3());
- ClassDB::bind_method(D_METHOD("add_torque", "torque"), &PhysicsDirectBodyState3D::add_torque);
ClassDB::bind_method(D_METHOD("apply_central_impulse", "impulse"), &PhysicsDirectBodyState3D::apply_central_impulse, Vector3());
ClassDB::bind_method(D_METHOD("apply_impulse", "impulse", "position"), &PhysicsDirectBodyState3D::apply_impulse, Vector3());
ClassDB::bind_method(D_METHOD("apply_torque_impulse", "impulse"), &PhysicsDirectBodyState3D::apply_torque_impulse);
+ ClassDB::bind_method(D_METHOD("apply_central_force", "force"), &PhysicsDirectBodyState3D::apply_central_force, Vector3());
+ ClassDB::bind_method(D_METHOD("apply_force", "force", "position"), &PhysicsDirectBodyState3D::apply_force, Vector3());
+ ClassDB::bind_method(D_METHOD("apply_torque", "torque"), &PhysicsDirectBodyState3D::apply_torque);
+
+ ClassDB::bind_method(D_METHOD("add_constant_central_force", "force"), &PhysicsDirectBodyState3D::add_constant_central_force, Vector3());
+ ClassDB::bind_method(D_METHOD("add_constant_force", "force", "position"), &PhysicsDirectBodyState3D::add_constant_force, Vector3());
+ ClassDB::bind_method(D_METHOD("add_constant_torque", "torque"), &PhysicsDirectBodyState3D::add_constant_torque);
+
+ ClassDB::bind_method(D_METHOD("set_constant_force", "force"), &PhysicsDirectBodyState3D::set_constant_force);
+ ClassDB::bind_method(D_METHOD("get_constant_force"), &PhysicsDirectBodyState3D::get_constant_force);
+
+ ClassDB::bind_method(D_METHOD("set_constant_torque", "torque"), &PhysicsDirectBodyState3D::set_constant_torque);
+ ClassDB::bind_method(D_METHOD("get_constant_torque"), &PhysicsDirectBodyState3D::get_constant_torque);
+
ClassDB::bind_method(D_METHOD("set_sleep_state", "enabled"), &PhysicsDirectBodyState3D::set_sleep_state);
ClassDB::bind_method(D_METHOD("is_sleeping"), &PhysicsDirectBodyState3D::is_sleeping);
@@ -731,13 +742,24 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_state", "body", "state", "value"), &PhysicsServer3D::body_set_state);
ClassDB::bind_method(D_METHOD("body_get_state", "body", "state"), &PhysicsServer3D::body_get_state);
- ClassDB::bind_method(D_METHOD("body_add_central_force", "body", "force"), &PhysicsServer3D::body_add_central_force);
- ClassDB::bind_method(D_METHOD("body_add_force", "body", "force", "position"), &PhysicsServer3D::body_add_force, Vector3());
- ClassDB::bind_method(D_METHOD("body_add_torque", "body", "torque"), &PhysicsServer3D::body_add_torque);
-
ClassDB::bind_method(D_METHOD("body_apply_central_impulse", "body", "impulse"), &PhysicsServer3D::body_apply_central_impulse);
ClassDB::bind_method(D_METHOD("body_apply_impulse", "body", "impulse", "position"), &PhysicsServer3D::body_apply_impulse, Vector3());
ClassDB::bind_method(D_METHOD("body_apply_torque_impulse", "body", "impulse"), &PhysicsServer3D::body_apply_torque_impulse);
+
+ ClassDB::bind_method(D_METHOD("body_apply_central_force", "body", "force"), &PhysicsServer3D::body_apply_central_force);
+ ClassDB::bind_method(D_METHOD("body_apply_force", "body", "force", "position"), &PhysicsServer3D::body_apply_force, Vector3());
+ ClassDB::bind_method(D_METHOD("body_apply_torque", "body", "torque"), &PhysicsServer3D::body_apply_torque);
+
+ ClassDB::bind_method(D_METHOD("body_add_constant_central_force", "body", "force"), &PhysicsServer3D::body_add_constant_central_force);
+ ClassDB::bind_method(D_METHOD("body_add_constant_force", "body", "force", "position"), &PhysicsServer3D::body_add_constant_force, Vector3());
+ ClassDB::bind_method(D_METHOD("body_add_constant_torque", "body", "torque"), &PhysicsServer3D::body_add_constant_torque);
+
+ ClassDB::bind_method(D_METHOD("body_set_constant_force", "body", "force"), &PhysicsServer3D::body_set_constant_force);
+ ClassDB::bind_method(D_METHOD("body_get_constant_force", "body"), &PhysicsServer3D::body_get_constant_force);
+
+ ClassDB::bind_method(D_METHOD("body_set_constant_torque", "body", "torque"), &PhysicsServer3D::body_set_constant_torque);
+ ClassDB::bind_method(D_METHOD("body_get_constant_torque", "body"), &PhysicsServer3D::body_get_constant_torque);
+
ClassDB::bind_method(D_METHOD("body_set_axis_velocity", "body", "axis_velocity"), &PhysicsServer3D::body_set_axis_velocity);
ClassDB::bind_method(D_METHOD("body_set_axis_lock", "body", "axis", "lock"), &PhysicsServer3D::body_set_axis_lock);
@@ -890,8 +912,6 @@ void PhysicsServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_active", "active"), &PhysicsServer3D::set_active);
- ClassDB::bind_method(D_METHOD("set_collision_iterations", "iterations"), &PhysicsServer3D::set_collision_iterations);
-
ClassDB::bind_method(D_METHOD("get_process_info", "process_info"), &PhysicsServer3D::get_process_info);
BIND_ENUM_CONSTANT(SHAPE_WORLD_BOUNDARY);
@@ -963,12 +983,12 @@ void PhysicsServer3D::_bind_methods() {
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_RECYCLE_RADIUS);
BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_SEPARATION);
- BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_CONTACT_DEFAULT_BIAS);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD);
BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_TIME_TO_SLEEP);
- BIND_ENUM_CONSTANT(SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO);
- BIND_ENUM_CONSTANT(SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS);
+ BIND_ENUM_CONSTANT(SPACE_PARAM_SOLVER_ITERATIONS);
BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_X);
BIND_ENUM_CONSTANT(BODY_AXIS_LINEAR_Y);
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 89a7eeee96..f830c95b58 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -65,13 +65,24 @@ public:
virtual Vector3 get_velocity_at_local_position(const Vector3 &p_position) const = 0;
- virtual void add_central_force(const Vector3 &p_force) = 0;
- virtual void add_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0;
- virtual void add_torque(const Vector3 &p_torque) = 0;
virtual void apply_central_impulse(const Vector3 &p_impulse) = 0;
virtual void apply_impulse(const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) = 0;
virtual void apply_torque_impulse(const Vector3 &p_impulse) = 0;
+ virtual void apply_central_force(const Vector3 &p_force) = 0;
+ virtual void apply_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0;
+ virtual void apply_torque(const Vector3 &p_torque) = 0;
+
+ virtual void add_constant_central_force(const Vector3 &p_force) = 0;
+ virtual void add_constant_force(const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0;
+ virtual void add_constant_torque(const Vector3 &p_torque) = 0;
+
+ virtual void set_constant_force(const Vector3 &p_force) = 0;
+ virtual Vector3 get_constant_force() const = 0;
+
+ virtual void set_constant_torque(const Vector3 &p_torque) = 0;
+ virtual Vector3 get_constant_torque() const = 0;
+
virtual void set_sleep_state(bool p_sleep) = 0;
virtual bool is_sleeping() const = 0;
@@ -263,12 +274,12 @@ public:
enum SpaceParameter {
SPACE_PARAM_CONTACT_RECYCLE_RADIUS,
SPACE_PARAM_CONTACT_MAX_SEPARATION,
- SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_MAX_ALLOWED_PENETRATION,
+ SPACE_PARAM_CONTACT_DEFAULT_BIAS,
SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD,
SPACE_PARAM_BODY_TIME_TO_SLEEP,
- SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO,
- SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS,
+ SPACE_PARAM_SOLVER_ITERATIONS,
};
virtual void space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) = 0;
@@ -434,20 +445,24 @@ public:
virtual void body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) = 0;
virtual Variant body_get_state(RID p_body, BodyState p_state) const = 0;
- //do something about it
- virtual void body_set_applied_force(RID p_body, const Vector3 &p_force) = 0;
- virtual Vector3 body_get_applied_force(RID p_body) const = 0;
-
- virtual void body_set_applied_torque(RID p_body, const Vector3 &p_torque) = 0;
- virtual Vector3 body_get_applied_torque(RID p_body) const = 0;
-
- virtual void body_add_central_force(RID p_body, const Vector3 &p_force) = 0;
- virtual void body_add_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0;
- virtual void body_add_torque(RID p_body, const Vector3 &p_torque) = 0;
-
virtual void body_apply_central_impulse(RID p_body, const Vector3 &p_impulse) = 0;
virtual void body_apply_impulse(RID p_body, const Vector3 &p_impulse, const Vector3 &p_position = Vector3()) = 0;
virtual void body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) = 0;
+
+ virtual void body_apply_central_force(RID p_body, const Vector3 &p_force) = 0;
+ virtual void body_apply_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0;
+ virtual void body_apply_torque(RID p_body, const Vector3 &p_torque) = 0;
+
+ virtual void body_add_constant_central_force(RID p_body, const Vector3 &p_force) = 0;
+ virtual void body_add_constant_force(RID p_body, const Vector3 &p_force, const Vector3 &p_position = Vector3()) = 0;
+ virtual void body_add_constant_torque(RID p_body, const Vector3 &p_torque) = 0;
+
+ virtual void body_set_constant_force(RID p_body, const Vector3 &p_force) = 0;
+ virtual Vector3 body_get_constant_force(RID p_body) const = 0;
+
+ virtual void body_set_constant_torque(RID p_body, const Vector3 &p_torque) = 0;
+ virtual Vector3 body_get_constant_torque(RID p_body) const = 0;
+
virtual void body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) = 0;
enum BodyAxis {
@@ -768,8 +783,6 @@ public:
virtual bool is_flushing_queries() const = 0;
- virtual void set_collision_iterations(int p_iterations) = 0;
-
enum ProcessInfo {
INFO_ACTIVE_OBJECTS,
INFO_COLLISION_PAIRS,
@@ -965,10 +978,9 @@ class PhysicsServer3DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/physics_server_3d_wrap_mt.cpp b/servers/physics_server_3d_wrap_mt.cpp
index c424100bba..822ca44b72 100644
--- a/servers/physics_server_3d_wrap_mt.cpp
+++ b/servers/physics_server_3d_wrap_mt.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/physics_server_3d_wrap_mt.h b/servers/physics_server_3d_wrap_mt.h
index 507427ecec..ecaef886e1 100644
--- a/servers/physics_server_3d_wrap_mt.h
+++ b/servers/physics_server_3d_wrap_mt.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -213,18 +213,24 @@ public:
FUNC3(body_set_state, RID, BodyState, const Variant &);
FUNC2RC(Variant, body_get_state, RID, BodyState);
- FUNC2(body_set_applied_force, RID, const Vector3 &);
- FUNC1RC(Vector3, body_get_applied_force, RID);
-
- FUNC2(body_set_applied_torque, RID, const Vector3 &);
- FUNC1RC(Vector3, body_get_applied_torque, RID);
-
- FUNC2(body_add_central_force, RID, const Vector3 &);
- FUNC3(body_add_force, RID, const Vector3 &, const Vector3 &);
- FUNC2(body_add_torque, RID, const Vector3 &);
FUNC2(body_apply_torque_impulse, RID, const Vector3 &);
FUNC2(body_apply_central_impulse, RID, const Vector3 &);
FUNC3(body_apply_impulse, RID, const Vector3 &, const Vector3 &);
+
+ FUNC2(body_apply_central_force, RID, const Vector3 &);
+ FUNC3(body_apply_force, RID, const Vector3 &, const Vector3 &);
+ FUNC2(body_apply_torque, RID, const Vector3 &);
+
+ FUNC2(body_add_constant_central_force, RID, const Vector3 &);
+ FUNC3(body_add_constant_force, RID, const Vector3 &, const Vector3 &);
+ FUNC2(body_add_constant_torque, RID, const Vector3 &);
+
+ FUNC2(body_set_constant_force, RID, const Vector3 &);
+ FUNC1RC(Vector3, body_get_constant_force, RID);
+
+ FUNC2(body_set_constant_torque, RID, const Vector3 &);
+ FUNC1RC(Vector3, body_get_constant_torque, RID);
+
FUNC2(body_set_axis_velocity, RID, const Vector3 &);
FUNC3(body_set_axis_lock, RID, BodyAxis, bool);
@@ -370,7 +376,6 @@ public:
FUNC1(free, RID);
FUNC1(set_active, bool);
- FUNC1(set_collision_iterations, int);
virtual void init() override;
virtual void step(real_t p_step) override;
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 7004b2317c..3fbf4fe436 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/register_server_types.h b/servers/register_server_types.h
index f6a65cb653..cf6364eee3 100644
--- a/servers/register_server_types.h
+++ b/servers/register_server_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h
index 3451ea2d39..67ad277c84 100644
--- a/servers/rendering/rasterizer_dummy.h
+++ b/servers/rendering/rasterizer_dummy.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -116,6 +116,8 @@ public:
void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) override {}
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) override {}
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) override {}
+ void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override {}
+ void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override {}
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, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) override {}
@@ -692,7 +694,9 @@ public:
virtual void update_memory_info() override {}
virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override { return 0; }
- bool has_os_feature(const String &p_feature) const override { return false; }
+ bool has_os_feature(const String &p_feature) const override {
+ return p_feature == "rgtc" || p_feature == "bptc" || p_feature == "s3tc" || p_feature == "etc" || p_feature == "etc2";
+ }
void update_dirty_resources() override {}
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 7b70483571..02af3c6eb9 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -786,7 +786,7 @@ void RendererCanvasCull::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
if (p_tile) {
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));
+ rect->source = Rect2(0, 0, ABS(p_rect.size.width), ABS(p_rect.size.height));
}
if (p_rect.size.x < 0) {
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index bdd61123df..fc53ce2327 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp
index 1945435586..3b68cd74fd 100644
--- a/servers/rendering/renderer_canvas_render.cpp
+++ b/servers/rendering/renderer_canvas_render.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
index 04ddae4089..1840925f78 100644
--- a/servers/rendering/renderer_canvas_render.h
+++ b/servers/rendering/renderer_canvas_render.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp
index 80c4625261..82e8bd6ef9 100644
--- a/servers/rendering/renderer_compositor.cpp
+++ b/servers/rendering/renderer_compositor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h
index 4526354d17..f245af9a4a 100644
--- a/servers/rendering/renderer_compositor.h
+++ b/servers/rendering/renderer_compositor.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index 4a98cf0831..6ad3556969 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h
index feafd4c2db..7f6750fa7e 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.h
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index cf943901d4..4a19519995 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1315,6 +1315,111 @@ void EffectsRD::bokeh_dof_raster(const BokehBuffers &p_buffers, bool p_dof_far,
}
}
+void EffectsRD::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection) {
+ // Downsample and deinterleave the depth buffer for SSAO and SSIL
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+ int downsample_pipeline = SS_EFFECTS_DOWNSAMPLE;
+ bool use_mips = p_ssao_quality > RS::ENV_SSAO_QUALITY_MEDIUM || p_ssil_quality > RS::ENV_SSIL_QUALITY_MEDIUM;
+
+ if (p_ssao_quality == RS::ENV_SSAO_QUALITY_VERY_LOW && p_ssil_quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_HALF;
+ } else if (use_mips) {
+ downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_MIPMAP;
+ }
+
+ bool use_half_size = false;
+ bool use_full_mips = false;
+
+ if (p_ssao_half_size && p_ssil_half_size) {
+ downsample_pipeline++;
+ use_half_size = true;
+ } else if (p_ssao_half_size != p_ssil_half_size) {
+ if (use_mips) {
+ downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_FULL_MIPS;
+ use_full_mips = true;
+ } else {
+ // Only need the first two mipmaps, but the cost to generate the next two is trivial
+ // TODO investigate the benefit of a shader version to generate only 2 mips
+ downsample_pipeline = SS_EFFECTS_DOWNSAMPLE_MIPMAP;
+ use_mips = true;
+ }
+ }
+
+ int depth_index = use_half_size ? 1 : 0;
+
+ RD::get_singleton()->draw_command_begin_label("Downsample Depth");
+ if (p_invalidate_uniform_set || use_full_mips != ss_effects.used_full_mips_last_frame || use_half_size != ss_effects.used_half_size_last_frame || use_mips != ss_effects.used_mips_last_frame) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.ids.push_back(p_depth_mipmaps[depth_index + 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[depth_index + 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[depth_index + 3]);
+ uniforms.push_back(u);
+ }
+ if (use_full_mips) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 3;
+ u.ids.push_back(p_depth_mipmaps[4]);
+ uniforms.push_back(u);
+ }
+ ss_effects.downsample_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, use_full_mips ? 6 : 2), 2);
+ }
+
+ 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;
+ }
+
+ ss_effects.downsample_push_constant.orthogonal = p_projection.is_orthogonal();
+ ss_effects.downsample_push_constant.z_near = depth_linearize_mul;
+ ss_effects.downsample_push_constant.z_far = depth_linearize_add;
+ if (ss_effects.downsample_push_constant.orthogonal) {
+ ss_effects.downsample_push_constant.z_near = p_projection.get_z_near();
+ ss_effects.downsample_push_constant.z_far = p_projection.get_z_far();
+ }
+ ss_effects.downsample_push_constant.pixel_size[0] = 1.0 / p_full_screen_size.x;
+ ss_effects.downsample_push_constant.pixel_size[1] = 1.0 / p_full_screen_size.y;
+ ss_effects.downsample_push_constant.radius_sq = 1.0;
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ss_effects.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[depth_index + 0]), 1);
+ if (use_mips) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, ss_effects.downsample_uniform_set, 2);
+ }
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ss_effects.downsample_push_constant, sizeof(SSEffectsDownsamplePushConstant));
+
+ Size2i size(MAX(1, p_full_screen_size.x >> (use_half_size ? 2 : 1)), MAX(1, p_full_screen_size.y >> (use_half_size ? 2 : 1)));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label();
+
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_COMPUTE);
+
+ ss_effects.used_full_mips_last_frame = use_mips;
+ ss_effects.used_full_mips_last_frame = use_full_mips;
+ ss_effects.used_half_size_last_frame = use_half_size;
+}
+
void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set) {
RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
if ((p_settings.quality == RS::ENV_SSAO_QUALITY_ULTRA) && !p_adaptive_base_pass) {
@@ -1341,82 +1446,12 @@ void EffectsRD::gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID>
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, RID &r_downsample_uniform_set, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set) {
+void EffectsRD::generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, 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, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->draw_command_begin_label("SSAO");
+ memset(&ssao.gather_push_constant, 0, sizeof(SSAOGatherPushConstant));
/* FIRST PASS */
- // Downsample and deinterleave the depth buffer.
- {
- RD::get_singleton()->draw_command_begin_label("Downsample Depth");
- 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);
- }
- r_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;
- }
-
- if (p_settings.half_size) {
- downsample_pipeline++;
- }
-
- 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, r_downsample_uniform_set, 2);
- }
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssao.downsample_push_constant, sizeof(SSAODownsamplePushConstant));
-
- Size2i size(MAX(1, p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1)), MAX(1, p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1)));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, size.x, size.y, 1);
- RD::get_singleton()->compute_list_add_barrier(compute_list);
- RD::get_singleton()->draw_command_end_label(); // Downsample SSAO
- }
+ RD::get_singleton()->draw_command_begin_label("Process Screen Space Ambient Occlusion");
/* SECOND PASS */
// Sample SSAO
{
@@ -1469,7 +1504,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
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(default_sampler);
u.ids.push_back(p_depth_mipmaps_texture);
uniforms.push_back(u);
}
@@ -1484,7 +1519,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 2;
- u.ids.push_back(ssao.gather_constants_buffer);
+ u.ids.push_back(ss_effects.gather_constants_buffer);
uniforms.push_back(u);
}
r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 0), 0);
@@ -1574,6 +1609,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
for (int pass = 0; pass < blur_passes; pass++) {
int blur_pipeline = SSAO_BLUR_PASS;
if (p_settings.quality > RS::ENV_SSAO_QUALITY_VERY_LOW) {
+ blur_pipeline = SSAO_BLUR_PASS_SMART;
if (pass < blur_passes - 2) {
blur_pipeline = SSAO_BLUR_PASS_WIDE;
} else {
@@ -1591,7 +1627,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
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_compute_uniform_set_from_texture_and_sampler(p_ao_slices[i], ss_effects.mirror_sampler), 0);
}
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_pong_slices[i]), 1);
@@ -1599,7 +1635,7 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
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_compute_uniform_set_from_texture_and_sampler(p_ao_pong_slices[i], ss_effects.mirror_sampler), 0);
}
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ao_slices[i]), 1);
}
@@ -1649,12 +1685,305 @@ void EffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, RID p_dep
RD::get_singleton()->draw_command_end_label(); // Interleave
}
RD::get_singleton()->draw_command_end_label(); //SSAO
- RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_TRANSFER); //wait for upcoming transfer
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //wait for upcoming transfer
int zero[1] = { 0 };
RD::get_singleton()->buffer_update(ssao.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
}
+void EffectsRD::gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set) {
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_gather_uniform_set, 0);
+ if ((p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) && !p_adaptive_base_pass) {
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_importance_map_uniform_set, 1);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, p_projection_uniform_set, 3);
+
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ ssil.gather_push_constant.pass_coord_offset[0] = i % 2;
+ ssil.gather_push_constant.pass_coord_offset[1] = i / 2;
+ ssil.gather_push_constant.pass_uv_offset[0] = ((i % 2) - 0.0) / p_settings.full_screen_size.x;
+ ssil.gather_push_constant.pass_uv_offset[1] = ((i / 2) - 0.0) / p_settings.full_screen_size.y;
+ ssil.gather_push_constant.pass = i;
+ RD::get_singleton()->compute_list_bind_uniform_set(p_compute_list, _get_compute_uniform_set_from_image_pair(p_ssil_slices[i], p_edges_slices[i]), 2);
+ RD::get_singleton()->compute_list_set_push_constant(p_compute_list, &ssil.gather_push_constant, sizeof(SSILGatherPushConstant));
+
+ Size2i size = Size2i(p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1), p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
+
+ RD::get_singleton()->compute_list_dispatch_threads(p_compute_list, size.x, size.y, 1);
+ }
+ RD::get_singleton()->compute_list_add_barrier(p_compute_list);
+}
+
+void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ssil, const Vector<RID> p_ssil_slices, RID p_ssil_pong, const Vector<RID> p_ssil_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set) {
+ RD::get_singleton()->draw_command_begin_label("Process Screen Space Indirect Lighting");
+ //Store projection info before starting the compute list
+ SSILProjectionUniforms projection_uniforms;
+ store_camera(p_last_projection, projection_uniforms.inv_last_frame_projection_matrix);
+
+ RD::get_singleton()->buffer_update(ssil.projection_uniform_buffer, 0, sizeof(SSILProjectionUniforms), &projection_uniforms);
+
+ memset(&ssil.gather_push_constant, 0, sizeof(SSILGatherPushConstant));
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ {
+ RD::get_singleton()->draw_command_begin_label("Gather Samples");
+ ssil.gather_push_constant.screen_size[0] = p_settings.full_screen_size.x;
+ ssil.gather_push_constant.screen_size[1] = p_settings.full_screen_size.y;
+
+ ssil.gather_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
+ ssil.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];
+ ssil.gather_push_constant.NDC_to_view_mul[0] = tan_half_fov_x * 2.0;
+ ssil.gather_push_constant.NDC_to_view_mul[1] = tan_half_fov_y * -2.0;
+ ssil.gather_push_constant.NDC_to_view_add[0] = tan_half_fov_x * -1.0;
+ ssil.gather_push_constant.NDC_to_view_add[1] = tan_half_fov_y;
+ ssil.gather_push_constant.z_near = p_projection.get_z_near();
+ ssil.gather_push_constant.z_far = p_projection.get_z_far();
+ ssil.gather_push_constant.is_orthogonal = p_projection.is_orthogonal();
+
+ ssil.gather_push_constant.half_screen_pixel_size_x025[0] = ssil.gather_push_constant.half_screen_pixel_size[0] * 0.25;
+ ssil.gather_push_constant.half_screen_pixel_size_x025[1] = ssil.gather_push_constant.half_screen_pixel_size[1] * 0.25;
+
+ ssil.gather_push_constant.radius = p_settings.radius;
+ float radius_near_limit = (p_settings.radius * 1.2f);
+ if (p_settings.quality <= RS::ENV_SSIL_QUALITY_LOW) {
+ radius_near_limit *= 1.50f;
+
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ ssil.gather_push_constant.radius *= 0.8f;
+ }
+ }
+ radius_near_limit /= tan_half_fov_y;
+ ssil.gather_push_constant.intensity = p_settings.intensity * Math_PI;
+ ssil.gather_push_constant.fade_out_mul = -1.0 / (p_settings.fadeout_to - p_settings.fadeout_from);
+ ssil.gather_push_constant.fade_out_add = p_settings.fadeout_from / (p_settings.fadeout_to - p_settings.fadeout_from) + 1.0;
+ ssil.gather_push_constant.inv_radius_near_limit = 1.0f / radius_near_limit;
+ ssil.gather_push_constant.neg_inv_radius = -1.0 / ssil.gather_push_constant.radius;
+ ssil.gather_push_constant.normal_rejection_amount = p_settings.normal_rejection;
+
+ ssil.gather_push_constant.load_counter_avg_div = 9.0 / float((p_settings.quarter_screen_size.x) * (p_settings.quarter_screen_size.y) * 255);
+ ssil.gather_push_constant.adaptive_sample_limit = p_settings.adaptive_target;
+
+ ssil.gather_push_constant.quality = MAX(0, p_settings.quality - 1);
+ ssil.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(default_mipmap_sampler);
+ u.ids.push_back(p_diffuse);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(ssil.projection_uniform_buffer);
+ uniforms.push_back(u);
+ }
+ r_projection_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 3);
+ }
+
+ 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(default_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(ss_effects.gather_constants_buffer);
+ uniforms.push_back(u);
+ }
+ r_gather_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 0), 0);
+ }
+
+ 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_ssil_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(ssil.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.gather_shader.version_get_shader(ssil.gather_shader_version, 2), 1);
+ }
+
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_ULTRA) {
+ RD::get_singleton()->draw_command_begin_label("Generate Importance Map");
+ ssil.importance_map_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
+ ssil.importance_map_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
+ ssil.importance_map_push_constant.intensity = p_settings.intensity * Math_PI;
+ //base pass
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_BASE]);
+ gather_ssil(compute_list, p_ssil_pong_slices, p_edges_slices, p_settings, true, r_gather_uniform_set, r_importance_map_uniform_set, r_projection_uniform_set);
+ //generate importance map
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GENERATE_IMPORTANCE_MAP]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_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, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ // process Importance Map A
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPA]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _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, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ // process Importance Map B
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_PROCESS_IMPORTANCE_MAPB]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _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, ssil.counter_uniform_set, 2);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.importance_map_push_constant, sizeof(SSILImportanceMapPushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.quarter_screen_size.x, p_settings.quarter_screen_size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+ RD::get_singleton()->draw_command_end_label(); // Importance Map
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER_ADAPTIVE]);
+ } else {
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[SSIL_GATHER]);
+ }
+
+ gather_ssil(compute_list, p_ssil_slices, p_edges_slices, p_settings, false, r_gather_uniform_set, r_importance_map_uniform_set, r_projection_uniform_set);
+ RD::get_singleton()->draw_command_end_label(); //Gather
+ }
+
+ {
+ RD::get_singleton()->draw_command_begin_label("Edge Aware Blur");
+ ssil.blur_push_constant.edge_sharpness = 1.0 - p_settings.sharpness;
+ ssil.blur_push_constant.half_screen_pixel_size[0] = 1.0 / p_settings.half_screen_size.x;
+ ssil.blur_push_constant.half_screen_pixel_size[1] = 1.0 / p_settings.half_screen_size.y;
+
+ int blur_passes = p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW ? p_settings.blur_passes : 1;
+
+ for (int pass = 0; pass < blur_passes; pass++) {
+ int blur_pipeline = SSIL_BLUR_PASS;
+ if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ blur_pipeline = SSIL_BLUR_PASS_SMART;
+ if (pass < blur_passes - 2) {
+ blur_pipeline = SSIL_BLUR_PASS_WIDE;
+ }
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if ((p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) && ((i == 1) || (i == 2))) {
+ continue;
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[blur_pipeline]);
+ if (pass % 2 == 0) {
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_slices[i]), 0);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ssil_slices[i], ss_effects.mirror_sampler), 0);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ssil_pong_slices[i]), 1);
+ } else {
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_pong_slices[i]), 0);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_and_sampler(p_ssil_pong_slices[i], ss_effects.mirror_sampler), 0);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_ssil_slices[i]), 1);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_edges_slices[i]), 2);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.blur_push_constant, sizeof(SSILBlurPushConstant));
+
+ int x_groups = (p_settings.full_screen_size.x >> (p_settings.half_size ? 2 : 1));
+ int y_groups = (p_settings.full_screen_size.y >> (p_settings.half_size ? 2 : 1));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, x_groups, y_groups, 1);
+ if (p_settings.quality > RS::ENV_SSIL_QUALITY_VERY_LOW) {
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ }
+ }
+ }
+
+ RD::get_singleton()->draw_command_end_label(); // Blur
+ }
+
+ {
+ RD::get_singleton()->draw_command_begin_label("Interleave Buffers");
+ ssil.interleave_push_constant.inv_sharpness = 1.0 - p_settings.sharpness;
+ ssil.interleave_push_constant.pixel_size[0] = 1.0 / p_settings.full_screen_size.x;
+ ssil.interleave_push_constant.pixel_size[1] = 1.0 / p_settings.full_screen_size.y;
+ ssil.interleave_push_constant.size_modifier = uint32_t(p_settings.half_size ? 4 : 2);
+
+ int interleave_pipeline = SSIL_INTERLEAVE_HALF;
+ if (p_settings.quality == RS::ENV_SSIL_QUALITY_LOW) {
+ interleave_pipeline = SSIL_INTERLEAVE;
+ } else if (p_settings.quality >= RS::ENV_SSIL_QUALITY_MEDIUM) {
+ interleave_pipeline = SSIL_INTERLEAVE_SMART;
+ }
+
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssil.pipelines[interleave_pipeline]);
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_destination), 0);
+
+ if (p_settings.quality > RS::ENV_SSIL_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_ssil), 1);
+ } else {
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ssil_pong), 1);
+ }
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_edges), 2);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssil.interleave_push_constant, sizeof(SSILInterleavePushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_settings.full_screen_size.x, p_settings.full_screen_size.y, 1);
+ RD::get_singleton()->compute_list_add_barrier(compute_list);
+ RD::get_singleton()->draw_command_end_label(); // Interleave
+ }
+
+ RD::get_singleton()->draw_command_end_label(); // SSIL
+
+ RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER);
+
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero, 0); //no barrier
+}
+
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;
@@ -2173,63 +2502,36 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
if (!prefer_raster_effects) {
- // 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");
- 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.downsample_shader.initialize(ssao_modes);
-
- ssao.downsample_shader_version = ssao.downsample_shader.version_create();
-
- 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");
- 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; 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++;
+ // Initialize depth buffer for screen space effects
+ Vector<String> downsampler_modes;
+ downsampler_modes.push_back("\n");
+ downsampler_modes.push_back("\n#define USE_HALF_SIZE\n");
+ downsampler_modes.push_back("\n#define GENERATE_MIPS\n");
+ downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define USE_HALF_SIZE\n");
+ downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n");
+ downsampler_modes.push_back("\n#define USE_HALF_BUFFERS\n#define USE_HALF_SIZE\n");
+ downsampler_modes.push_back("\n#define GENERATE_MIPS\n#define GENERATE_FULL_MIPS");
+
+ ss_effects.downsample_shader.initialize(downsampler_modes);
+
+ ss_effects.downsample_shader_version = ss_effects.downsample_shader.version_create();
+
+ for (int i = 0; i < SS_EFFECTS_MAX; i++) {
+ ss_effects.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ss_effects.downsample_shader.version_get_shader(ss_effects.downsample_shader_version, i));
}
- ssao.gather_constants_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSAOGatherConstants));
- SSAOGatherConstants gather_constants;
+ ss_effects.gather_constants_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSEffectsGatherConstants));
+ SSEffectsGatherConstants 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 };
- int b = spmap[subPass];
+ b = spmap[subPass];
float ca, sa;
float angle0 = (float(a) + float(b) / float(sub_pass_count)) * Math_PI * 0.5f;
@@ -2246,72 +2548,105 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
}
- RD::get_singleton()->buffer_update(ssao.gather_constants_buffer, 0, sizeof(SSAOGatherConstants), &gather_constants);
+ RD::get_singleton()->buffer_update(ss_effects.gather_constants_buffer, 0, sizeof(SSEffectsGatherConstants), &gather_constants);
}
+
{
- Vector<String> ssao_modes;
- 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");
+ // Initialize ssao
- ssao.importance_map_shader.initialize(ssao_modes);
+ 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.importance_map_shader_version = ssao.importance_map_shader.version_create();
+ ss_effects.mirror_sampler = RD::get_singleton()->sampler_create(sampler);
- 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));
+ uint32_t pipeline = 0;
+ {
+ Vector<String> ssao_modes;
- 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);
- RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter");
+ ssao_modes.push_back("\n");
+ ssao_modes.push_back("\n#define SSAO_BASE\n");
+ ssao_modes.push_back("\n#define ADAPTIVE\n");
- Vector<RD::Uniform> uniforms;
+ ssao.gather_shader.initialize(ssao_modes);
+
+ ssao.gather_shader_version = ssao.gather_shader.version_create();
+
+ for (int i = 0; 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));
+ pipeline++;
+ }
+ }
{
- 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);
+ Vector<String> ssao_modes;
+ 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);
+ RD::get_singleton()->set_resource_name(ssao.importance_map_load_counter, "Importance Map Load Counter");
+
+ 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);
+ RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set");
}
- 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);
- RD::get_singleton()->set_resource_name(ssao.counter_uniform_set, "Load Counter Uniform Set");
- }
- {
- 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");
+ {
+ 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.initialize(ssao_modes);
- ssao.blur_shader_version = ssao.blur_shader.version_create();
+ ssao.blur_shader_version = ssao.blur_shader.version_create();
- 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));
+ 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++;
+ 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));
- RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i));
- 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));
+ RD::get_singleton()->set_resource_name(ssao.pipelines[pipeline], "Interleave Pipeline " + itos(i));
+ pipeline++;
+ }
}
- }
- ERR_FAIL_COND(pipeline != SSAO_MAX);
+ ERR_FAIL_COND(pipeline != SSAO_MAX);
+ }
}
if (!prefer_raster_effects) {
@@ -2504,6 +2839,79 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
{
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n");
+ ssil_modes.push_back("\n#define SSIL_BASE\n");
+ ssil_modes.push_back("\n#define ADAPTIVE\n");
+
+ ssil.gather_shader.initialize(ssil_modes);
+
+ ssil.gather_shader_version = ssil.gather_shader.version_create();
+
+ for (int i = SSIL_GATHER; i <= SSIL_GATHER_ADAPTIVE; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.gather_shader.version_get_shader(ssil.gather_shader_version, i));
+ }
+ ssil.projection_uniform_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(SSILProjectionUniforms));
+ }
+
+ {
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n#define GENERATE_MAP\n");
+ ssil_modes.push_back("\n#define PROCESS_MAPA\n");
+ ssil_modes.push_back("\n#define PROCESS_MAPB\n");
+
+ ssil.importance_map_shader.initialize(ssil_modes);
+
+ ssil.importance_map_shader_version = ssil.importance_map_shader.version_create();
+
+ for (int i = SSIL_GENERATE_IMPORTANCE_MAP; i <= SSIL_PROCESS_IMPORTANCE_MAPB; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, i - SSIL_GENERATE_IMPORTANCE_MAP));
+ }
+ ssil.importance_map_load_counter = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t));
+ int zero[1] = { 0 };
+ RD::get_singleton()->buffer_update(ssil.importance_map_load_counter, 0, sizeof(uint32_t), &zero);
+ RD::get_singleton()->set_resource_name(ssil.importance_map_load_counter, "Importance Map Load Counter");
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(ssil.importance_map_load_counter);
+ uniforms.push_back(u);
+ }
+ ssil.counter_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssil.importance_map_shader.version_get_shader(ssil.importance_map_shader_version, 2), 2);
+ RD::get_singleton()->set_resource_name(ssil.counter_uniform_set, "Load Counter Uniform Set");
+ }
+ {
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssil_modes.push_back("\n#define MODE_SMART\n");
+ ssil_modes.push_back("\n#define MODE_WIDE\n");
+
+ ssil.blur_shader.initialize(ssil_modes);
+
+ ssil.blur_shader_version = ssil.blur_shader.version_create();
+ for (int i = SSIL_BLUR_PASS; i <= SSIL_BLUR_PASS_WIDE; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.blur_shader.version_get_shader(ssil.blur_shader_version, i - SSIL_BLUR_PASS));
+ }
+ }
+
+ {
+ Vector<String> ssil_modes;
+ ssil_modes.push_back("\n#define MODE_NON_SMART\n");
+ ssil_modes.push_back("\n#define MODE_SMART\n");
+ ssil_modes.push_back("\n#define MODE_HALF\n");
+
+ ssil.interleave_shader.initialize(ssil_modes);
+
+ ssil.interleave_shader_version = ssil.interleave_shader.version_create();
+ for (int i = SSIL_INTERLEAVE; i <= SSIL_INTERLEAVE_HALF; i++) {
+ ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, i - SSIL_INTERLEAVE));
+ }
+ }
+
+ {
Vector<String> resolve_modes;
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
@@ -2600,20 +3008,26 @@ EffectsRD::~EffectsRD() {
copy.shader.version_free(copy.shader_version);
resolve.shader.version_free(resolve.shader_version);
specular_merge.shader.version_free(specular_merge.shader_version);
+ ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version);
ssao.blur_shader.version_free(ssao.blur_shader_version);
ssao.gather_shader.version_free(ssao.gather_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);
+ ssil.blur_shader.version_free(ssil.blur_shader_version);
+ ssil.gather_shader.version_free(ssil.gather_shader_version);
+ ssil.interleave_shader.version_free(ssil.interleave_shader_version);
+ ssil.importance_map_shader.version_free(ssil.importance_map_shader_version);
roughness_limiter.shader.version_free(roughness_limiter.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);
sss.shader.version_free(sss.shader_version);
- RD::get_singleton()->free(ssao.mirror_sampler);
- RD::get_singleton()->free(ssao.gather_constants_buffer);
+ RD::get_singleton()->free(ss_effects.mirror_sampler);
+ RD::get_singleton()->free(ss_effects.gather_constants_buffer);
RD::get_singleton()->free(ssao.importance_map_load_counter);
+ RD::get_singleton()->free(ssil.importance_map_load_counter);
+ RD::get_singleton()->free(ssil.projection_uniform_buffer);
}
copy_to_fb.shader.version_free(copy_to_fb.shader_version);
cube_to_dp.shader.version_free(cube_to_dp.shader_version);
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index 6037127e82..747f2c8941 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,11 +55,15 @@
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.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/ss_effects_downsample.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/ssil.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssil_blur.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/ssil_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/renderer_scene_render.h"
@@ -399,13 +403,47 @@ private:
PipelineCacheRD raster_pipelines[BOKEH_MAX];
} bokeh;
+ struct SSEffectsDownsamplePushConstant {
+ float pixel_size[2];
+ float z_far;
+ float z_near;
+ uint32_t orthogonal;
+ float radius_sq;
+ uint32_t pad[2];
+ };
+
+ enum SSEffectsMode {
+ SS_EFFECTS_DOWNSAMPLE,
+ SS_EFFECTS_DOWNSAMPLE_HALF_RES,
+ SS_EFFECTS_DOWNSAMPLE_MIPMAP,
+ SS_EFFECTS_DOWNSAMPLE_MIPMAP_HALF_RES,
+ SS_EFFECTS_DOWNSAMPLE_HALF,
+ SS_EFFECTS_DOWNSAMPLE_HALF_RES_HALF,
+ SS_EFFECTS_DOWNSAMPLE_FULL_MIPS,
+ SS_EFFECTS_MAX
+ };
+
+ struct SSEffectsGatherConstants {
+ float rotation_matrices[80]; //5 vec4s * 4
+ };
+
+ struct SSEffects {
+ SSEffectsDownsamplePushConstant downsample_push_constant;
+ SsEffectsDownsampleShaderRD downsample_shader;
+ RID downsample_shader_version;
+ RID downsample_uniform_set;
+ bool used_half_size_last_frame = false;
+ bool used_mips_last_frame = false;
+ bool used_full_mips_last_frame = false;
+
+ RID gather_constants_buffer;
+
+ RID mirror_sampler;
+
+ RID pipelines[SS_EFFECTS_MAX];
+ } ss_effects;
+
enum SSAOMode {
- 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,
@@ -421,15 +459,6 @@ private:
SSAO_MAX
};
- struct SSAODownsamplePushConstant {
- float pixel_size[2];
- float z_far;
- float z_near;
- uint32_t orthogonal;
- float radius_sq;
- uint32_t pad[2];
- };
-
struct SSAOGatherPushConstant {
int32_t screen_size[2];
int pass;
@@ -455,7 +484,7 @@ private:
float horizon_angle_threshold;
float inv_radius_near_limit;
- bool is_orthogonal;
+ uint32_t is_orthogonal;
float neg_inv_radius;
float load_counter_avg_div;
float adaptive_sample_limit;
@@ -464,10 +493,6 @@ private:
float pass_uv_offset[2];
};
- struct SSAOGatherConstants {
- float rotation_matrices[80]; //5 vec4s * 4
- };
-
struct SSAOImportanceMapPushConstant {
float half_screen_pixel_size[2];
float intensity;
@@ -487,15 +512,9 @@ private:
};
struct SSAO {
- SSAODownsamplePushConstant downsample_push_constant;
- SsaoDownsampleShaderRD downsample_shader;
- RID downsample_shader_version;
-
SSAOGatherPushConstant gather_push_constant;
SsaoShaderRD gather_shader;
RID gather_shader_version;
- RID gather_constants_buffer;
- bool gather_initialized = false;
SSAOImportanceMapPushConstant importance_map_push_constant;
SsaoImportanceMapShaderRD importance_map_shader;
@@ -511,10 +530,104 @@ private:
SsaoInterleaveShaderRD interleave_shader;
RID interleave_shader_version;
- RID mirror_sampler;
RID pipelines[SSAO_MAX];
} ssao;
+ enum SSILMode {
+ SSIL_GATHER,
+ SSIL_GATHER_BASE,
+ SSIL_GATHER_ADAPTIVE,
+ SSIL_GENERATE_IMPORTANCE_MAP,
+ SSIL_PROCESS_IMPORTANCE_MAPA,
+ SSIL_PROCESS_IMPORTANCE_MAPB,
+ SSIL_BLUR_PASS,
+ SSIL_BLUR_PASS_SMART,
+ SSIL_BLUR_PASS_WIDE,
+ SSIL_INTERLEAVE,
+ SSIL_INTERLEAVE_SMART,
+ SSIL_INTERLEAVE_HALF,
+ SSIL_MAX
+ };
+
+ struct SSILGatherPushConstant {
+ int32_t screen_size[2];
+ int pass;
+ int quality;
+
+ float half_screen_pixel_size[2];
+ float half_screen_pixel_size_x025[2];
+
+ float NDC_to_view_mul[2];
+ float NDC_to_view_add[2];
+
+ float pad2[2];
+ float z_near;
+ float z_far;
+
+ float radius;
+ float intensity;
+ int size_multiplier;
+ int pad;
+
+ float fade_out_mul;
+ float fade_out_add;
+ float normal_rejection_amount;
+ float inv_radius_near_limit;
+
+ uint32_t 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 SSILImportanceMapPushConstant {
+ float half_screen_pixel_size[2];
+ float intensity;
+ float pad;
+ };
+
+ struct SSILBlurPushConstant {
+ float edge_sharpness;
+ float pad;
+ float half_screen_pixel_size[2];
+ };
+
+ struct SSILInterleavePushConstant {
+ float inv_sharpness;
+ uint32_t size_modifier;
+ float pixel_size[2];
+ };
+
+ struct SSILProjectionUniforms {
+ float inv_last_frame_projection_matrix[16];
+ };
+
+ struct SSIL {
+ SSILGatherPushConstant gather_push_constant;
+ SsilShaderRD gather_shader;
+ RID gather_shader_version;
+ RID projection_uniform_buffer;
+
+ SSILImportanceMapPushConstant importance_map_push_constant;
+ SsilImportanceMapShaderRD importance_map_shader;
+ RID importance_map_shader_version;
+ RID importance_map_load_counter;
+ RID counter_uniform_set;
+
+ SSILBlurPushConstant blur_push_constant;
+ SsilBlurShaderRD blur_shader;
+ RID blur_shader_version;
+
+ SSILInterleavePushConstant interleave_push_constant;
+ SsilInterleaveShaderRD interleave_shader;
+ RID interleave_shader_version;
+
+ RID pipelines[SSIL_MAX];
+ } ssil;
+
struct RoughnessLimiterPushConstant {
int32_t screen_size[2];
float curve;
@@ -615,6 +728,7 @@ private:
uint8_t metallic_mask[4];
float projection[16];
+ float prev_projection[16];
};
struct ScreenSpaceReflection {
@@ -879,11 +993,34 @@ public:
Size2i quarter_screen_size = Size2i();
};
+ struct SSILSettings {
+ float radius = 1.0;
+ float intensity = 2.0;
+ float sharpness = 0.98;
+ float normal_rejection = 1.0;
+
+ RS::EnvironmentSSILQuality quality = RS::ENV_SSIL_QUALITY_MEDIUM;
+ bool half_size = true;
+ float adaptive_target = 0.5;
+ int blur_passes = 4;
+ 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 tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_color, RD::FramebufferFormatID p_dst_format_id, const TonemapSettings &p_settings);
+ void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection);
+
void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
- void 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, RID &r_downsample_uniform_set, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set);
+ void generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, 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, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set);
+
+ void gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set);
+ void screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set);
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);
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 8fb276b8fb..1771ade012 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -730,7 +730,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.ambient_light_color_energy[3] = 1.0;
scene_state.ubo.use_ambient_cubemap = false;
scene_state.ubo.use_reflection_cubemap = false;
- scene_state.ubo.ssao_enabled = false;
+ scene_state.ubo.ss_effects_flags = 0;
} else if (is_environment(p_render_data->environment)) {
RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment);
@@ -775,9 +775,14 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.use_reflection_cubemap = false;
}
- scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_is_ssao_enabled(p_render_data->environment);
scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_affect(p_render_data->environment);
scene_state.ubo.ssao_light_affect = environment_get_ssao_light_affect(p_render_data->environment);
+ uint32_t ss_flags = 0;
+ if (p_opaque_render_buffers) {
+ ss_flags |= environment_is_ssao_enabled(p_render_data->environment) ? 1 : 0;
+ ss_flags |= environment_is_ssil_enabled(p_render_data->environment) ? 2 : 0;
+ }
+ scene_state.ubo.ss_effects_flags = ss_flags;
scene_state.ubo.fog_enabled = environment_is_fog_enabled(p_render_data->environment);
scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
@@ -809,7 +814,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.use_ambient_cubemap = false;
scene_state.ubo.use_reflection_cubemap = false;
- scene_state.ubo.ssao_enabled = false;
+ scene_state.ubo.ss_effects_flags = 0;
}
scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active();
@@ -1225,6 +1230,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool using_sdfgi = false;
bool using_voxelgi = false;
bool reverse_cull = false;
+ bool using_ssil = p_render_data->environment.is_valid() && environment_is_ssil_enabled(p_render_data->environment);
if (render_buffer) {
screen_size.x = render_buffer->width;
@@ -1254,7 +1260,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
opaque_specular_framebuffer = render_buffer->color_specular_fb;
}
- } else if (p_render_data->environment.is_valid() && (environment_is_ssao_enabled(p_render_data->environment) || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) {
+ } else if (p_render_data->environment.is_valid() && (environment_is_ssao_enabled(p_render_data->environment) || using_ssil || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER)) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS;
}
@@ -1449,7 +1455,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
continue_depth = !finish_depth;
}
- _pre_opaque_render(p_render_data, using_ssao, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->voxelgi_buffer : RID());
+ _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->voxelgi_buffer : RID());
RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
@@ -1594,6 +1600,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_end_label();
+ RENDER_TIMESTAMP("Resolve");
+
RD::get_singleton()->draw_command_begin_label("Resolve");
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
@@ -1602,6 +1610,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_end_label();
+ RD::get_singleton()->draw_command_begin_label("Copy framebuffer for SSIL");
+ if (using_ssil) {
+ RENDER_TIMESTAMP("Copy Final Framebuffer");
+ _copy_framebuffer_to_ssil(p_render_data->render_buffers);
+ }
+ RD::get_singleton()->draw_command_end_label();
+
if (p_render_data->render_buffers.is_valid()) {
_debug_draw_cluster(p_render_data->render_buffers);
@@ -2372,6 +2387,15 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
u.ids.push_back(vfog);
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.binding = 19;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ RID ssil = rb ? render_buffers_get_ssil_texture(p_render_data->render_buffers) : RID();
+ RID texture = ssil.is_valid() ? ssil : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.ids.push_back(texture);
+ uniforms.push_back(u);
+ }
}
if (p_index >= (int)render_pass_uniform_sets.size()) {
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index d6ab4d1db2..b2309996a7 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -251,7 +251,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float z_far;
float z_near;
- uint32_t ssao_enabled;
+ uint32_t ss_effects_flags;
float ssao_light_affect;
float ssao_ao_affect;
uint32_t roughness_limiter_enabled;
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index 768bd1de9d..0cdcbc952d 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -44,7 +44,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
uniforms.clear();
uses_screen_texture = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index f2a55939f4..98448ce846 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 445623fb86..fc2bc1cadf 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -669,7 +669,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
}
- _pre_opaque_render(p_render_data, false, false, RID(), RID());
+ _pre_opaque_render(p_render_data, false, false, false, RID(), RID());
uint32_t spec_constant_base_flags = 0;
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index 485d08b589..0ef1fe6ceb 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index e6d9a60f94..9b96cc18bc 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -47,7 +47,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) {
uniforms.clear();
uses_screen_texture = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index 392fac1e3e..770f9bde3b 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
index 0d60052666..e812a48d3d 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/pipeline_cache_rd.h b/servers/rendering/renderer_rd/pipeline_cache_rd.h
index e52f47fa47..8d82480b38 100644
--- a/servers/rendering/renderer_rd/pipeline_cache_rd.h
+++ b/servers/rendering/renderer_rd/pipeline_cache_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index d013099cce..704a164a3a 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1953,7 +1953,7 @@ void RendererCanvasRenderRD::ShaderData::set_code(const String &p_code) {
uses_sdf = false;
uses_time = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 26ccbd3bf5..c9544a5239 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 522a8e8112..2f8ef696cd 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -240,7 +240,7 @@ RendererCompositorRD *RendererCompositorRD::singleton = nullptr;
RendererCompositorRD::RendererCompositorRD() {
{
String shader_cache_dir = Engine::get_singleton()->get_shader_cache_path();
- if (shader_cache_dir == String()) {
+ if (shader_cache_dir.is_empty()) {
shader_cache_dir = "user://";
}
DirAccessRef da = DirAccess::open(shader_cache_dir);
@@ -261,7 +261,7 @@ RendererCompositorRD::RendererCompositorRD() {
shader_cache_dir = String(); //disable only if not editor
}
- if (shader_cache_dir != String()) {
+ if (!shader_cache_dir.is_empty()) {
bool compress = GLOBAL_GET("rendering/shader_compiler/shader_cache/compress");
bool use_zstd = GLOBAL_GET("rendering/shader_compiler/shader_cache/use_zstd_compression");
bool strip_debug = GLOBAL_GET("rendering/shader_compiler/shader_cache/strip_debug");
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index f69e40e0ff..9a992d5819 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
index 550e59ba98..7ea117ef33 100644
--- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_environment_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
index ec9cb4a798..9e36a61870 100644
--- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -123,6 +123,14 @@ public:
float ssr_fade_out = 2.0;
float ssr_depth_tolerance = 0.2;
+ /// SSIL
+ ///
+ bool ssil_enabled = false;
+ float ssil_radius = 5.0;
+ float ssil_intensity = 1.0;
+ float ssil_sharpness = 0.98;
+ float ssil_normal_rejection = 1.0;
+
/// SDFGI
bool sdfgi_enabled = false;
RS::EnvironmentSDFGICascades sdfgi_cascades;
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
index b6b5c90b39..73cb088f6a 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1305,7 +1305,6 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
RD::get_singleton()->draw_list_draw(p_draw_list, false, total_probes, total_points);
if (gi->sdfgi_debug_probe_dir != Vector3()) {
- print_line("CLICK DEBUG ME?");
uint32_t cascade = 0;
Vector3 offset = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascades[cascade].position)) * cascades[cascade].cell_size * Vector3(1.0, 1.0 / y_mult, 1.0);
Vector3 probe_size = cascades[cascade].cell_size * (cascade_size / SDFGI::PROBE_DIVISOR) * Vector3(1.0, 1.0 / y_mult, 1.0);
@@ -1333,11 +1332,6 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
}
}
- if (gi->sdfgi_debug_probe_enabled) {
- print_line("found: " + gi->sdfgi_debug_probe_index);
- } else {
- print_line("no found");
- }
gi->sdfgi_debug_probe_dir = Vector3();
}
@@ -1864,7 +1858,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region,
Ref<Image> img;
img.instantiate();
for (uint32_t i = 0; i < cascade_size; i++) {
- Vector<uint8_t> subarr = data.subarray(128 * 128 * i, 128 * 128 * (i + 1) - 1);
+ Vector<uint8_t> subarr = data.slice(128 * 128 * i, 128 * 128 * (i + 1));
img->create(cascade_size, cascade_size, false, Image::FORMAT_L8, subarr);
img->save_png("res://cascade_sdf_" + itos(cascade) + "_" + itos(i) + ".png");
}
@@ -1877,7 +1871,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region,
Ref<Image> img;
img.instantiate();
for (uint32_t i = 0; i < cascade_size; i++) {
- Vector<uint8_t> subarr = data.subarray(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2 - 1);
+ Vector<uint8_t> subarr = data.slice(128 * 128 * i * 2, 128 * 128 * (i + 1) * 2);
img->createcascade_size, cascade_size, false, Image::FORMAT_RGB565, subarr);
img->convert(Image::FORMAT_RGBA8);
img->save_png("res://cascade_" + itos(cascade) + "_" + itos(i) + ".png");
@@ -2065,7 +2059,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
for (int i = 0; i < levels.size(); i++) {
VoxelGIInstance::Mipmap mipmap;
- mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, RD::TEXTURE_SLICE_3D);
+ mipmap.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), texture, 0, i, 1, RD::TEXTURE_SLICE_3D);
mipmap.level = levels.size() - i - 1;
mipmap.cell_offset = 0;
for (uint32_t j = 0; j < mipmap.level; j++) {
@@ -2182,8 +2176,9 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
dmap.texture = RD::get_singleton()->texture_create(dtf, RD::TextureView());
if (dynamic_maps.size() == 0) {
- //render depth for first one
- dtf.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;
+ // Render depth for first one.
+ // Use 16-bit depth when supported to improve performance.
+ dtf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D16_UNORM, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
dtf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
dmap.fb_depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
index 9f6fc8a9b7..a407199d0a 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -602,19 +602,15 @@ public:
};
struct VoxelGIData {
- float xform[16];
- float bounds[3];
- float dynamic_range;
+ float xform[16]; // 64 - 64
- float bias;
- float normal_bias;
- uint32_t blend_ambient;
- uint32_t texture_slot;
+ float bounds[3]; // 12 - 76
+ float dynamic_range; // 4 - 80
- uint32_t pad0;
- uint32_t pad1;
- uint32_t pad2;
- uint32_t mipmaps;
+ float bias; // 4 - 84
+ float normal_bias; // 4 - 88
+ uint32_t blend_ambient; // 4 - 92
+ uint32_t mipmaps; // 4 - 96
};
struct PushConstant {
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index ae8d91a73b..1297f49724 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -427,6 +427,26 @@ void RendererSceneRenderRD::environment_set_ssao_quality(RS::EnvironmentSSAOQual
ssao_fadeout_to = p_fadeout_to;
}
+void RendererSceneRenderRD::environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) {
+ RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->ssil_enabled = p_enable;
+ env->ssil_radius = p_radius;
+ env->ssil_intensity = p_intensity;
+ env->ssil_sharpness = p_sharpness;
+ env->ssil_normal_rejection = p_normal_rejection;
+}
+
+void RendererSceneRenderRD::environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) {
+ ssil_quality = p_quality;
+ ssil_half_size = p_half_size;
+ ssil_adaptive_target = p_adaptive_target;
+ ssil_blur_passes = p_blur_passes;
+ ssil_fadeout_from = p_fadeout_from;
+ ssil_fadeout_to = p_fadeout_to;
+}
+
bool RendererSceneRenderRD::environment_is_ssao_enabled(RID p_env) const {
RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env);
ERR_FAIL_COND_V(!env, false);
@@ -445,6 +465,12 @@ float RendererSceneRenderRD::environment_get_ssao_light_affect(RID p_env) const
return env->ssao_direct_light_affect;
}
+bool RendererSceneRenderRD::environment_is_ssil_enabled(RID p_env) const {
+ RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env);
+ ERR_FAIL_COND_V(!env, false);
+ return env->ssil_enabled;
+}
+
bool RendererSceneRenderRD::environment_is_ssr_enabled(RID p_env) const {
RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_env);
ERR_FAIL_COND_V(!env, false);
@@ -1798,24 +1824,51 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->luminance.current = RID();
}
- if (rb->ssao.depth.is_valid()) {
- RD::get_singleton()->free(rb->ssao.depth);
- RD::get_singleton()->free(rb->ssao.ao_deinterleaved);
- RD::get_singleton()->free(rb->ssao.ao_pong);
- RD::get_singleton()->free(rb->ssao.ao_final);
+ if (rb->ss_effects.linear_depth.is_valid()) {
+ RD::get_singleton()->free(rb->ss_effects.linear_depth);
+ rb->ss_effects.linear_depth = RID();
+ rb->ss_effects.linear_depth_slices.clear();
+ }
+
+ if (rb->ss_effects.ssao.ao_final.is_valid()) {
+ RD::get_singleton()->free(rb->ss_effects.ssao.ao_deinterleaved);
+ RD::get_singleton()->free(rb->ss_effects.ssao.ao_pong);
+ RD::get_singleton()->free(rb->ss_effects.ssao.ao_final);
+
+ RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[0]);
+ RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[1]);
+
+ rb->ss_effects.ssao.ao_deinterleaved = RID();
+ rb->ss_effects.ssao.ao_pong = RID();
+ rb->ss_effects.ssao.ao_final = RID();
+ rb->ss_effects.ssao.importance_map[0] = RID();
+ rb->ss_effects.ssao.importance_map[1] = RID();
+
+ rb->ss_effects.ssao.ao_deinterleaved_slices.clear();
+ rb->ss_effects.ssao.ao_pong_slices.clear();
+ }
+
+ if (rb->ss_effects.ssil.ssil_final.is_valid()) {
+ RD::get_singleton()->free(rb->ss_effects.ssil.ssil_final);
+ RD::get_singleton()->free(rb->ss_effects.ssil.deinterleaved);
+ RD::get_singleton()->free(rb->ss_effects.ssil.pong);
+ RD::get_singleton()->free(rb->ss_effects.ssil.edges);
+ RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[0]);
+ RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[1]);
- RD::get_singleton()->free(rb->ssao.importance_map[0]);
- RD::get_singleton()->free(rb->ssao.importance_map[1]);
+ rb->ss_effects.ssil.ssil_final = RID();
+ rb->ss_effects.ssil.deinterleaved = RID();
+ rb->ss_effects.ssil.pong = RID();
+ rb->ss_effects.ssil.edges = RID();
+ rb->ss_effects.ssil.deinterleaved_slices.clear();
+ rb->ss_effects.ssil.pong_slices.clear();
+ rb->ss_effects.ssil.edges_slices.clear();
+ rb->ss_effects.ssil.importance_map[0] = RID();
+ rb->ss_effects.ssil.importance_map[1] = RID();
- rb->ssao.depth = 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();
+ RD::get_singleton()->free(rb->ss_effects.last_frame);
+ rb->ss_effects.last_frame = RID();
+ rb->ss_effects.last_frame_slices.clear();
}
if (rb->ssr.blur_radius[0].is_valid()) {
@@ -1919,24 +1972,21 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
RENDER_TIMESTAMP("Process SSAO");
- 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_deinterleaved);
- RD::get_singleton()->free(rb->ssao.ao_pong);
- RD::get_singleton()->free(rb->ssao.ao_final);
+ if (rb->ss_effects.ssao.ao_final.is_valid() && ssao_using_half_size != ssao_half_size) {
+ RD::get_singleton()->free(rb->ss_effects.ssao.ao_deinterleaved);
+ RD::get_singleton()->free(rb->ss_effects.ssao.ao_pong);
+ RD::get_singleton()->free(rb->ss_effects.ssao.ao_final);
- RD::get_singleton()->free(rb->ssao.importance_map[0]);
- RD::get_singleton()->free(rb->ssao.importance_map[1]);
+ RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[0]);
+ RD::get_singleton()->free(rb->ss_effects.ssao.importance_map[1]);
- rb->ssao.depth = 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();
+ rb->ss_effects.ssao.ao_deinterleaved = RID();
+ rb->ss_effects.ssao.ao_pong = RID();
+ rb->ss_effects.ssao.ao_final = RID();
+ rb->ss_effects.ssao.importance_map[0] = RID();
+ rb->ss_effects.ssao.importance_map[1] = RID();
+ rb->ss_effects.ssao.ao_deinterleaved_slices.clear();
+ rb->ss_effects.ssao.ao_pong_slices.clear();
}
int buffer_width;
@@ -1955,27 +2005,10 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
half_height = (rb->internal_height + 3) / 4;
}
bool uniform_sets_are_invalid = false;
- if (rb->ssao.depth.is_null()) {
- //allocate depth slices
-
+ if (rb->ss_effects.ssao.ao_deinterleaved.is_null()) {
{
- RD::TextureFormat tf;
- 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());
- RD::get_singleton()->set_resource_name(rb->ssao.depth, "SSAO Depth");
- 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, RD::TEXTURE_SLICE_2D_ARRAY);
- rb->ssao.depth_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(rb->ssao.depth_slices[i], "SSAO Depth Mip " + itos(i) + " ");
- }
+ rb->ss_effects.ssao.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.linear_depth, 0, ssao_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
}
-
{
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8_UNORM;
@@ -1984,12 +2017,12 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
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());
- RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved, "SSAO De-interleaved Array");
+ rb->ss_effects.ssao.ao_deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_deinterleaved, "SSAO De-interleaved Array");
for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_deinterleaved, i, 0);
- rb->ssao.ao_deinterleaved_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved_slices[i], "SSAO De-interleaved Array Layer " + itos(i) + " ");
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssao.ao_deinterleaved, i, 0);
+ rb->ss_effects.ssao.ao_deinterleaved_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " ");
}
}
@@ -2001,12 +2034,12 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
tf.height = buffer_height;
tf.array_layers = 4;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ssao.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ssao.ao_pong, "SSAO De-interleaved Array Pong");
+ rb->ss_effects.ssao.ao_pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_pong, "SSAO De-interleaved Array Pong");
for (uint32_t i = 0; i < 4; i++) {
- RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.ao_pong, i, 0);
- rb->ssao.ao_pong_slices.push_back(slice);
- RD::get_singleton()->set_resource_name(rb->ssao.ao_deinterleaved_slices[i], "SSAO De-interleaved Array Layer " + itos(i) + " Pong");
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssao.ao_pong, i, 0);
+ rb->ss_effects.ssao.ao_pong_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSAO De-interleaved Array Layer " + itos(i) + " Pong");
}
}
@@ -2016,10 +2049,10 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
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());
- RD::get_singleton()->set_resource_name(rb->ssao.importance_map[0], "SSAO Importance Map");
- rb->ssao.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ssao.importance_map[1], "SSAO Importance Map Pong");
+ rb->ss_effects.ssao.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.importance_map[0], "SSAO Importance Map");
+ rb->ss_effects.ssao.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.importance_map[1], "SSAO Importance Map Pong");
}
{
RD::TextureFormat tf;
@@ -2027,8 +2060,8 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
tf.width = rb->internal_width;
tf.height = rb->internal_height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->ssao.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
- RD::get_singleton()->set_resource_name(rb->ssao.ao_final, "SSAO Final");
+ rb->ss_effects.ssao.ao_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssao.ao_final, "SSAO Final");
}
ssao_using_half_size = ssao_half_size;
uniform_sets_are_invalid = true;
@@ -2052,7 +2085,187 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
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, rb->ssao.downsample_uniform_set, rb->ssao.gather_uniform_set, rb->ssao.importance_map_uniform_set);
+ storage->get_effects()->generate_ssao(p_normal_buffer, rb->ss_effects.ssao.depth_texture_view, rb->ss_effects.ssao.ao_deinterleaved, rb->ss_effects.ssao.ao_deinterleaved_slices, rb->ss_effects.ssao.ao_pong, rb->ss_effects.ssao.ao_pong_slices, rb->ss_effects.ssao.ao_final, rb->ss_effects.ssao.importance_map[0], rb->ss_effects.ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssao.gather_uniform_set, rb->ss_effects.ssao.importance_map_uniform_set);
+}
+
+void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform) {
+ RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
+ ERR_FAIL_COND(!rb);
+
+ RendererSceneEnvironmentRD *env = environment_owner.get_or_null(p_environment);
+ ERR_FAIL_COND(!env);
+
+ RENDER_TIMESTAMP("Process SSIL");
+
+ if (rb->ss_effects.ssil.ssil_final.is_valid() && ssil_using_half_size != ssil_half_size) {
+ RD::get_singleton()->free(rb->ss_effects.ssil.ssil_final);
+ RD::get_singleton()->free(rb->ss_effects.ssil.deinterleaved);
+ RD::get_singleton()->free(rb->ss_effects.ssil.pong);
+ RD::get_singleton()->free(rb->ss_effects.ssil.edges);
+ RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[0]);
+ RD::get_singleton()->free(rb->ss_effects.ssil.importance_map[1]);
+
+ rb->ss_effects.ssil.ssil_final = RID();
+ rb->ss_effects.ssil.deinterleaved = RID();
+ rb->ss_effects.ssil.pong = RID();
+ rb->ss_effects.ssil.edges = RID();
+ rb->ss_effects.ssil.deinterleaved_slices.clear();
+ rb->ss_effects.ssil.pong_slices.clear();
+ rb->ss_effects.ssil.edges_slices.clear();
+ rb->ss_effects.ssil.importance_map[0] = RID();
+ rb->ss_effects.ssil.importance_map[1] = RID();
+ }
+
+ int buffer_width;
+ int buffer_height;
+ int half_width;
+ int half_height;
+ if (ssil_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;
+ }
+ bool uniform_sets_are_invalid = false;
+ if (rb->ss_effects.ssil.ssil_final.is_null()) {
+ {
+ rb->ss_effects.ssil.depth_texture_view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.linear_depth, 0, ssil_half_size ? 1 : 0, 4, RD::TEXTURE_SLICE_2D_ARRAY);
+ }
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.width = rb->width;
+ tf.height = rb->height;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ rb->ss_effects.ssil.ssil_final = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.ssil_final, "SSIL texture");
+ RD::get_singleton()->texture_clear(rb->ss_effects.ssil.ssil_final, Color(0, 0, 0, 0), 0, 1, 0, 1);
+ if (rb->ss_effects.last_frame.is_null()) {
+ tf.mipmaps = 6;
+ rb->ss_effects.last_frame = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.last_frame, "Last Frame Radiance");
+ RD::get_singleton()->texture_clear(rb->ss_effects.last_frame, Color(0, 0, 0, 0), 0, tf.mipmaps, 0, 1);
+ for (uint32_t i = 0; i < 6; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.last_frame, 0, i);
+ rb->ss_effects.last_frame_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "Last Frame Radiance Mip " + itos(i) + " ");
+ }
+ }
+ }
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = buffer_width;
+ tf.height = buffer_height;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->ss_effects.ssil.deinterleaved = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.deinterleaved, "SSIL deinterleaved buffer");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.deinterleaved, i, 0);
+ rb->ss_effects.ssil.deinterleaved_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer array " + itos(i) + " ");
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ 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->ss_effects.ssil.pong = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.pong, "SSIL deinterleaved pong buffer");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.pong, i, 0);
+ rb->ss_effects.ssil.pong_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSIL deinterleaved buffer pong array " + itos(i) + " ");
+ }
+ }
+
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_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->ss_effects.ssil.edges = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.edges, "SSIL edges buffer");
+ for (uint32_t i = 0; i < 4; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.ssil.edges, i, 0);
+ rb->ss_effects.ssil.edges_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SSIL edges buffer slice " + itos(i) + " ");
+ }
+ }
+
+ {
+ 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->ss_effects.ssil.importance_map[0] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.importance_map[0], "SSIL Importance Map");
+ rb->ss_effects.ssil.importance_map[1] = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.ssil.importance_map[1], "SSIL Importance Map Pong");
+ }
+ uniform_sets_are_invalid = true;
+ ssil_using_half_size = ssil_half_size;
+ }
+
+ EffectsRD::SSILSettings settings;
+ settings.radius = env->ssil_radius;
+ settings.intensity = env->ssil_intensity;
+ settings.sharpness = env->ssil_sharpness;
+ settings.normal_rejection = env->ssil_normal_rejection;
+
+ settings.quality = ssil_quality;
+ settings.half_size = ssil_half_size;
+ settings.adaptive_target = ssil_adaptive_target;
+ settings.blur_passes = ssil_blur_passes;
+ settings.fadeout_from = ssil_fadeout_from;
+ settings.fadeout_to = ssil_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);
+
+ CameraMatrix correction;
+ correction.set_depth_correction(true);
+ CameraMatrix projection = correction * p_projection;
+ Transform3D transform = p_transform;
+ transform.set_origin(Vector3(0.0, 0.0, 0.0));
+ CameraMatrix last_frame_projection = rb->ss_effects.last_frame_projection * CameraMatrix(rb->ss_effects.last_frame_transform.affine_inverse()) * CameraMatrix(transform) * projection.inverse();
+
+ storage->get_effects()->screen_space_indirect_lighting(rb->ss_effects.last_frame, rb->ss_effects.ssil.ssil_final, p_normal_buffer, rb->ss_effects.ssil.depth_texture_view, rb->ss_effects.ssil.deinterleaved, rb->ss_effects.ssil.deinterleaved_slices, rb->ss_effects.ssil.pong, rb->ss_effects.ssil.pong_slices, rb->ss_effects.ssil.importance_map[0], rb->ss_effects.ssil.importance_map[1], rb->ss_effects.ssil.edges, rb->ss_effects.ssil.edges_slices, p_projection, last_frame_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssil.gather_uniform_set, rb->ss_effects.ssil.importance_map_uniform_set, rb->ss_effects.ssil.projection_uniform_set);
+ rb->ss_effects.last_frame_projection = projection;
+ rb->ss_effects.last_frame_transform = transform;
+}
+
+void RendererSceneRenderRD::_copy_framebuffer_to_ssil(RID p_render_buffers) {
+ RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
+ ERR_FAIL_COND(!rb);
+
+ if (rb->ss_effects.last_frame.is_valid()) {
+ storage->get_effects()->copy_to_rect(rb->texture, rb->ss_effects.last_frame, Rect2i(0, 0, rb->width, rb->height));
+
+ int width = rb->width;
+ int height = rb->height;
+ for (int i = 0; i < rb->ss_effects.last_frame_slices.size() - 1; i++) {
+ width = MAX(1, width >> 1);
+ height = MAX(1, height >> 1);
+ storage->get_effects()->make_mipmap(rb->ss_effects.last_frame_slices[i], rb->ss_effects.last_frame_slices[i + 1], Size2i(width, height));
+ }
+ }
}
void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) {
@@ -2427,10 +2640,14 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
}
}
- if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao_final.is_valid()) {
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ss_effects.ssao.ao_final.is_valid()) {
+ Size2 rtsize = storage->render_target_get_size(rb->render_target);
+ effects->copy_to_fb_rect(rb->ss_effects.ssao.ao_final, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
+ }
+
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb->ss_effects.ssil.ssil_final.is_valid()) {
Size2 rtsize = storage->render_target_get_size(rb->render_target);
- 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);
+ effects->copy_to_fb_rect(rb->ss_effects.ssil.ssil_final, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(p_render_buffers).is_valid()) {
@@ -2494,7 +2711,13 @@ RID RendererSceneRenderRD::render_buffers_get_ao_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- return rb->ssao.ao_final;
+ return rb->ss_effects.ssao.ao_final;
+}
+RID RendererSceneRenderRD::render_buffers_get_ssil_texture(RID p_render_buffers) {
+ RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
+ ERR_FAIL_COND_V(!rb, RID());
+
+ return rb->ss_effects.ssil.ssil_final;
}
RID RendererSceneRenderRD::render_buffers_get_voxel_gi_buffer(RID p_render_buffers) {
@@ -3581,7 +3804,7 @@ void RendererSceneRenderRD::FogShaderData::set_code(const String &p_code) {
ubo_size = 0;
uniforms.clear();
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
@@ -4417,9 +4640,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
uint32_t cluster_screen_width = (rb->width - 1) / cluster_size + 1;
uint32_t cluster_screen_height = (rb->height - 1) / cluster_size + 1;
- params.cluster_type_size = cluster_screen_width * cluster_screen_height * (32 + 32);
- params.cluster_width = cluster_screen_width;
params.max_cluster_element_count_div_32 = max_cluster_elements / 32;
+ params.cluster_type_size = cluster_screen_width * cluster_screen_height * (params.max_cluster_element_count_div_32 + 32);
+ params.cluster_width = cluster_screen_width;
params.screen_size[0] = rb->width;
params.screen_size[1] = rb->height;
@@ -4528,7 +4751,7 @@ void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, boo
}
}
-void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer) {
+void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer) {
// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
if (p_render_data->render_buffers.is_valid() && p_use_gi) {
@@ -4615,9 +4838,40 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
}
if (p_render_data->render_buffers.is_valid()) {
+ if (p_use_ssao || p_use_ssil) {
+ RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
+ ERR_FAIL_COND(!rb);
+
+ bool invalidate_uniform_set = false;
+ if (rb->ss_effects.linear_depth.is_null()) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16_SFLOAT;
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.width = (rb->width + 1) / 2;
+ tf.height = (rb->height + 1) / 2;
+ tf.mipmaps = 5;
+ tf.array_layers = 4;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ rb->ss_effects.linear_depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rb->ss_effects.linear_depth, "SS Effects Depth");
+ for (uint32_t i = 0; i < tf.mipmaps; i++) {
+ RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ss_effects.linear_depth, 0, i, 1, RD::TEXTURE_SLICE_2D_ARRAY);
+ rb->ss_effects.linear_depth_slices.push_back(slice);
+ RD::get_singleton()->set_resource_name(slice, "SS Effects Depth Mip " + itos(i) + " ");
+ }
+ invalidate_uniform_set = true;
+ }
+
+ storage->get_effects()->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection);
+ }
+
if (p_use_ssao) {
_process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection);
}
+
+ if (p_use_ssil) {
+ _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection, p_render_data->cam_transform);
+ }
}
//full barrier here, we need raster, transfer and compute and it depends from the previous work
@@ -5499,6 +5753,9 @@ void fog() {
sss_quality = RS::SubSurfaceScatteringQuality(int(GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_quality")));
sss_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_scale");
sss_depth_scale = GLOBAL_GET("rendering/environment/subsurface_scattering/subsurface_scattering_depth_scale");
+
+ environment_set_ssil_quality(RS::EnvironmentSSILQuality(int(GLOBAL_GET("rendering/environment/ssil/quality"))), GLOBAL_GET("rendering/environment/ssil/half_size"), GLOBAL_GET("rendering/environment/ssil/adaptive_target"), GLOBAL_GET("rendering/environment/ssil/blur_passes"), GLOBAL_GET("rendering/environment/ssil/fadeout_from"), GLOBAL_GET("rendering/environment/ssil/fadeout_to"));
+
directional_penumbra_shadow_kernel = memnew_arr(float, 128);
directional_soft_shadow_kernel = memnew_arr(float, 128);
penumbra_shadow_kernel = memnew_arr(float, 128);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 98ab1a2c3c..55891bc2a9 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -129,12 +129,15 @@ protected:
void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection);
void _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 _process_sss(RID p_render_buffers, const CameraMatrix &p_camera);
+ void _process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform);
+ void _copy_framebuffer_to_ssil(RID p_render_buffers);
+ void _ensure_ss_effects(RID p_render_buffers, bool p_using_ssil);
bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
- void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer);
+ void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer);
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
@@ -415,6 +418,14 @@ private:
float ssao_fadeout_from = 50.0;
float ssao_fadeout_to = 300.0;
+ RS::EnvironmentSSILQuality ssil_quality = RS::ENV_SSIL_QUALITY_MEDIUM;
+ bool ssil_half_size = false;
+ bool ssil_using_half_size = false;
+ float ssil_adaptive_target = 0.5;
+ int ssil_blur_passes = 4;
+ float ssil_fadeout_from = 50.0;
+ float ssil_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;
@@ -524,20 +535,47 @@ private:
RID current_fb;
} luminance;
- struct SSAO {
- RID depth;
- Vector<RID> depth_slices;
- RID ao_deinterleaved;
- Vector<RID> ao_deinterleaved_slices;
- RID ao_pong;
- Vector<RID> ao_pong_slices;
- RID ao_final;
- RID importance_map[2];
+ struct SSEffects {
+ RID linear_depth;
+ Vector<RID> linear_depth_slices;
RID downsample_uniform_set;
- RID gather_uniform_set;
- RID importance_map_uniform_set;
- } ssao;
+
+ RID last_frame;
+ Vector<RID> last_frame_slices;
+
+ CameraMatrix last_frame_projection;
+ Transform3D last_frame_transform;
+
+ struct SSAO {
+ RID ao_deinterleaved;
+ Vector<RID> ao_deinterleaved_slices;
+ RID ao_pong;
+ Vector<RID> ao_pong_slices;
+ RID ao_final;
+ RID importance_map[2];
+ RID depth_texture_view;
+
+ RID gather_uniform_set;
+ RID importance_map_uniform_set;
+ } ssao;
+
+ struct SSIL {
+ RID ssil_final;
+ RID deinterleaved;
+ Vector<RID> deinterleaved_slices;
+ RID pong;
+ Vector<RID> pong_slices;
+ RID edges;
+ Vector<RID> edges_slices;
+ RID importance_map[2];
+ RID depth_texture_view;
+
+ RID gather_uniform_set;
+ RID importance_map_uniform_set;
+ RID projection_uniform_set;
+ } ssil;
+ } ss_effects;
struct SSR {
RID normal_scaled;
@@ -1046,9 +1084,12 @@ public:
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) override;
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) override;
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) override;
+ virtual void environment_set_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) override;
+ virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) override;
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;
+ bool environment_is_ssil_enabled(RID p_env) const;
bool environment_is_ssr_enabled(RID p_env) const;
bool environment_is_sdfgi_enabled(RID p_env) const;
@@ -1344,6 +1385,7 @@ public:
RID render_buffers_get_depth_texture(RID p_render_buffers);
RID render_buffers_get_ao_texture(RID p_render_buffers);
+ RID render_buffers_get_ssil_texture(RID p_render_buffers);
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
RID render_buffers_get_back_depth_texture(RID p_render_buffers);
RID render_buffers_get_voxel_gi_buffer(RID p_render_buffers);
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index a9c39fb937..8fb3c607fa 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -46,7 +46,7 @@ void RendererSceneSkyRD::SkyShaderData::set_code(const String &p_code) {
ubo_size = 0;
uniforms.clear();
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
@@ -360,7 +360,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR
mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
}
- layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6, j, RD::TEXTURE_SLICE_CUBEMAP);
+ layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer + i * 6, j, 1, RD::TEXTURE_SLICE_CUBEMAP);
mmw = MAX(1, mmw >> 1);
mmh = MAX(1, mmh >> 1);
@@ -388,7 +388,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR
mm.framebuffers[k] = RD::get_singleton()->framebuffer_create(fbtex);
}
- layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, j, RD::TEXTURE_SLICE_CUBEMAP);
+ layer.views.write[j] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, j, 1, RD::TEXTURE_SLICE_CUBEMAP);
mmw = MAX(1, mmw >> 1);
mmh = MAX(1, mmh >> 1);
@@ -397,7 +397,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR
layers.push_back(layer);
}
- radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, RD::TEXTURE_SLICE_CUBEMAP);
+ radiance_base_cubemap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), p_base_cube, p_base_layer, 0, 1, RD::TEXTURE_SLICE_CUBEMAP);
RD::get_singleton()->set_resource_name(radiance_base_cubemap, "radiance base cubemap");
RD::TextureFormat tf;
tf.format = p_texture_format;
@@ -418,7 +418,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR
ReflectionData::DownsampleLayer::Mipmap &mm = downsampled_layer.mipmaps.write[j];
mm.size.width = mmw;
mm.size.height = mmh;
- mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, 0, j, RD::TEXTURE_SLICE_CUBEMAP);
+ mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, 0, j, 1, RD::TEXTURE_SLICE_CUBEMAP);
RD::get_singleton()->set_resource_name(mm.view, "Downsampled Radiance Cubemap Mip " + itos(j) + " ");
if (prefer_raster_effects) {
// we need a framebuffer for each side of our cubemap
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
index 8689395bea..1359cdec67 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 29e4a63cbb..496dde123d 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1089,7 +1089,7 @@ Vector<Ref<Image>> RendererStorageRD::texture_3d_get(RID p_texture) const {
const Texture::BufferSlice3D &bs = tex->buffer_slices_3d[i];
ERR_FAIL_COND_V(bs.offset >= (uint32_t)all_data.size(), Vector<Ref<Image>>());
ERR_FAIL_COND_V(bs.offset + bs.buffer_size > (uint32_t)all_data.size(), Vector<Ref<Image>>());
- Vector<uint8_t> sub_region = all_data.subarray(bs.offset, bs.offset + bs.buffer_size - 1);
+ Vector<uint8_t> sub_region = all_data.slice(bs.offset, bs.offset + bs.buffer_size);
Ref<Image> img;
img.instantiate();
@@ -2655,13 +2655,13 @@ void RendererStorageRD::MaterialData::update_uniform_buffer(const Map<StringName
uint32_t size = 0U;
// The following code enforces a 16-byte alignment of uniform arrays.
if (E.value.array_size > 0) {
- size = ShaderLanguage::get_type_size(E.value.type) * E.value.array_size;
+ size = ShaderLanguage::get_datatype_size(E.value.type) * E.value.array_size;
int m = (16 * E.value.array_size);
if ((size % m) != 0U) {
size += m - (size % m);
}
} else {
- size = ShaderLanguage::get_type_size(E.value.type);
+ size = ShaderLanguage::get_datatype_size(E.value.type);
}
ERR_CONTINUE(offset + size > p_buffer_size);
#endif
@@ -2818,11 +2818,14 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: {
rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_BLACK);
} break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_NONE: {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: {
+ rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_ANISO);
+ } break;
+ case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL);
} break;
- case ShaderLanguage::ShaderNode::Uniform::HINT_ANISO: {
- rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_ANISO);
+ case ShaderLanguage::ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL: {
+ rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL);
} break;
default: {
rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE);
@@ -2861,7 +2864,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
}
}
#ifdef TOOLS_ENABLED
- if (roughness_detect_texture && normal_detect_texture && normal_detect_texture->path != String()) {
+ if (roughness_detect_texture && normal_detect_texture && !normal_detect_texture->path.is_empty()) {
roughness_detect_texture->detect_roughness_callback(roughness_detect_texture->detect_roughness_callback_ud, normal_detect_texture->path, roughness_channel);
}
#endif
@@ -2901,7 +2904,7 @@ void RendererStorageRD::MaterialData::update_textures(const Map<StringName, Vari
rd_texture = singleton->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE);
}
#ifdef TOOLS_ENABLED
- if (roughness_detect_texture && normal_detect_texture && normal_detect_texture->path != String()) {
+ if (roughness_detect_texture && normal_detect_texture && !normal_detect_texture->path.is_empty()) {
roughness_detect_texture->detect_roughness_callback(roughness_detect_texture->detect_roughness_callback_ud, normal_detect_texture->path, roughness_channel);
}
#endif
@@ -5820,7 +5823,7 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) {
uniforms.clear();
uses_collision = false;
- if (code == String()) {
+ if (code.is_empty()) {
return; //just invalid, but no error
}
@@ -9234,7 +9237,7 @@ void RendererStorageRD::_update_global_variables() {
for (uint32_t i = 0; i < total_regions; i++) {
if (global_variables.buffer_dirty_regions[i]) {
- RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, global_variables.buffer_values);
+ RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, &global_variables.buffer_values[i * GlobalVariables::BUFFER_DIRTY_REGION_SIZE]);
global_variables.buffer_dirty_regions[i] = false;
}
@@ -9265,7 +9268,6 @@ void RendererStorageRD::_update_global_variables() {
ERR_CONTINUE(!material); //wtf
_material_queue_update(material, false, true);
- print_line("update material texture?");
}
global_variables.must_update_texture_materials = false;
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index 9a64480c3e..8f044dbe75 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
index 77d3a2e766..38ac00176f 100644
--- a/servers/rendering/renderer_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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,81 +54,6 @@ static String _typestr(SL::DataType p_type) {
return type;
}
-static int _get_datatype_size(SL::DataType p_type) {
- switch (p_type) {
- case SL::TYPE_VOID:
- return 0;
- case SL::TYPE_BOOL:
- return 4;
- case SL::TYPE_BVEC2:
- return 8;
- case SL::TYPE_BVEC3:
- return 12;
- case SL::TYPE_BVEC4:
- return 16;
- case SL::TYPE_INT:
- return 4;
- case SL::TYPE_IVEC2:
- return 8;
- case SL::TYPE_IVEC3:
- return 12;
- case SL::TYPE_IVEC4:
- return 16;
- case SL::TYPE_UINT:
- return 4;
- case SL::TYPE_UVEC2:
- return 8;
- case SL::TYPE_UVEC3:
- return 12;
- case SL::TYPE_UVEC4:
- return 16;
- case SL::TYPE_FLOAT:
- return 4;
- case SL::TYPE_VEC2:
- return 8;
- case SL::TYPE_VEC3:
- return 12;
- case SL::TYPE_VEC4:
- return 16;
- case SL::TYPE_MAT2:
- return 32; // 4 * 4 + 4 * 4
- case SL::TYPE_MAT3:
- return 48; // 4 * 4 + 4 * 4 + 4 * 4
- case SL::TYPE_MAT4:
- return 64;
- case SL::TYPE_SAMPLER2D:
- return 16;
- case SL::TYPE_ISAMPLER2D:
- return 16;
- case SL::TYPE_USAMPLER2D:
- return 16;
- case SL::TYPE_SAMPLER2DARRAY:
- return 16;
- case SL::TYPE_ISAMPLER2DARRAY:
- return 16;
- case SL::TYPE_USAMPLER2DARRAY:
- return 16;
- case SL::TYPE_SAMPLER3D:
- return 16;
- case SL::TYPE_ISAMPLER3D:
- return 16;
- case SL::TYPE_USAMPLER3D:
- return 16;
- case SL::TYPE_SAMPLERCUBE:
- return 16;
- case SL::TYPE_SAMPLERCUBEARRAY:
- return 16;
- case SL::TYPE_STRUCT:
- return 0;
-
- case SL::TYPE_MAX: {
- ERR_FAIL_V(0);
- };
- }
-
- ERR_FAIL_V(0);
-}
-
static int _get_datatype_alignment(SL::DataType p_type) {
switch (p_type) {
case SL::TYPE_VOID:
@@ -658,12 +583,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
uniform_defines.write[uniform.order] = ucode;
if (is_buffer_global) {
//globals are indices into the global table
- uniform_sizes.write[uniform.order] = _get_datatype_size(ShaderLanguage::TYPE_UINT);
+ uniform_sizes.write[uniform.order] = ShaderLanguage::get_datatype_size(ShaderLanguage::TYPE_UINT);
uniform_alignments.write[uniform.order] = _get_datatype_alignment(ShaderLanguage::TYPE_UINT);
} else {
// The following code enforces a 16-byte alignment of uniform arrays.
if (uniform.array_size > 0) {
- int size = _get_datatype_size(uniform.type) * uniform.array_size;
+ int size = ShaderLanguage::get_datatype_size(uniform.type) * uniform.array_size;
int m = (16 * uniform.array_size);
if ((size % m) != 0) {
size += m - (size % m);
@@ -671,7 +596,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
uniform_sizes.write[uniform.order] = size;
uniform_alignments.write[uniform.order] = 16;
} else {
- uniform_sizes.write[uniform.order] = _get_datatype_size(uniform.type);
+ uniform_sizes.write[uniform.order] = ShaderLanguage::get_datatype_size(uniform.type);
uniform_alignments.write[uniform.order] = _get_datatype_alignment(uniform.type);
}
}
@@ -1318,6 +1243,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += ")";
} break;
+ case SL::OP_EMPTY: {
+ // Semicolon (or empty statement) - ignored.
+ } break;
default: {
if (p_use_scope) {
@@ -1410,7 +1338,13 @@ ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &
}
Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
- Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderLanguage::VaryingFunctionNames(), ShaderTypes::get_singleton()->get_types(), _get_variable_type);
+ SL::ShaderCompileInfo info;
+ info.functions = ShaderTypes::get_singleton()->get_functions(p_mode);
+ info.render_modes = ShaderTypes::get_singleton()->get_modes(p_mode);
+ info.shader_types = ShaderTypes::get_singleton()->get_types();
+ info.global_variable_type_func = _get_variable_type;
+
+ Error err = parser.compile(p_code, info);
if (err != OK) {
Vector<String> shader = p_code.split("\n");
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.h b/servers/rendering/renderer_rd/shader_compiler_rd.h
index 2ab689c27c..5670d881f6 100644
--- a/servers/rendering/renderer_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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp
index 2568090918..73766d14d8 100644
--- a/servers/rendering/renderer_rd/shader_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_rd.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -79,7 +79,7 @@ void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) {
}
if (push_chunk) {
- if (text != String()) {
+ if (!text.is_empty()) {
StageTemplate::Chunk text_chunk;
text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
text_chunk.text = text.utf8();
@@ -90,7 +90,7 @@ void ShaderRD::_add_stage(const char *p_code, StageType p_stage_type) {
}
}
- if (text != String()) {
+ if (!text.is_empty()) {
StageTemplate::Chunk text_chunk;
text_chunk.type = StageTemplate::Chunk::TYPE_TEXT;
text_chunk.text = text.utf8();
@@ -638,7 +638,7 @@ void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String
variants_enabled.push_back(true);
}
- if (shader_cache_dir != String()) {
+ if (!shader_cache_dir.is_empty()) {
StringBuilder hash_build;
hash_build.append("[base_hash]");
diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h
index 984b168659..06f78ab193 100644
--- a/servers/rendering/renderer_rd/shader_rd.h
+++ b/servers/rendering/renderer_rd/shader_rd.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/shaders/copy.glsl b/servers/rendering/renderer_rd/shaders/copy.glsl
index 4110a95ddb..a89f83b5c4 100644
--- a/servers/rendering/renderer_rd/shaders/copy.glsl
+++ b/servers/rendering/renderer_rd/shaders/copy.glsl
@@ -84,6 +84,8 @@ void main() {
color += texelFetch(source_color, base_pos + ivec2(1, 0), 0);
color += texelFetch(source_color, base_pos + ivec2(1, 1), 0);
color /= 4.0;
+ color = mix(color, vec4(100.0, 100.0, 100.0, 1.0), isinf(color));
+ color = mix(color, vec4(100.0, 100.0, 100.0, 1.0), isnan(color));
imageStore(dest_buffer, pos + params.target, color);
#endif
@@ -132,6 +134,13 @@ void main() {
local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0);
local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0);
}
+ if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
+ // Tonemap initial samples to reduce weight of fireflies: https://graphicrants.blogspot.com/2013/12/tone-mapping.html
+ local_cache[dest_index] /= 1.0 + dot(local_cache[dest_index].rgb, vec3(0.299, 0.587, 0.114));
+ local_cache[dest_index + 1] /= 1.0 + dot(local_cache[dest_index + 1].rgb, vec3(0.299, 0.587, 0.114));
+ local_cache[dest_index + 16] /= 1.0 + dot(local_cache[dest_index + 16].rgb, vec3(0.299, 0.587, 0.114));
+ local_cache[dest_index + 16 + 1] /= 1.0 + dot(local_cache[dest_index + 16 + 1].rgb, vec3(0.299, 0.587, 0.114));
+ }
memoryBarrierShared();
barrier();
@@ -177,6 +186,11 @@ void main() {
color += temp_cache[index - 2] * 0.140367;
color += temp_cache[index - 3] * 0.106595;
+ if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
+ // Undo tonemap to restore range: https://graphicrants.blogspot.com/2013/12/tone-mapping.html
+ color /= 1.0 - dot(color.rgb, vec3(0.299, 0.587, 0.114));
+ }
+
color *= params.glow_strength;
if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
@@ -186,7 +200,7 @@ void main() {
#endif
color *= params.glow_exposure;
- float luminance = max(color.r, max(color.g, color.b));
+ float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114));
float feedback = max(smoothstep(params.glow_hdr_threshold, params.glow_hdr_threshold + params.glow_hdr_scale, luminance), params.glow_bloom);
color = min(color * feedback, vec4(params.glow_luminance_cap));
diff --git a/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl b/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl
index 4e2ba84033..54a7790f77 100644
--- a/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl
+++ b/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl
index 5528ea3659..9854f124d7 100644
--- a/servers/rendering/renderer_rd/shaders/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/gi.glsl
@@ -68,19 +68,15 @@ sdfgi;
#define MAX_VOXEL_GI_INSTANCES 8
struct VoxelGIData {
- mat4 xform;
- vec3 bounds;
- float dynamic_range;
+ mat4 xform; // 64 - 64
- float bias;
- float normal_bias;
- bool blend_ambient;
- uint texture_slot;
+ vec3 bounds; // 12 - 76
+ float dynamic_range; // 4 - 80
- uint pad0;
- uint pad1;
- uint pad2;
- uint mipmaps;
+ float bias; // 4 - 84
+ float normal_bias; // 4 - 88
+ bool blend_ambient; // 4 - 92
+ uint mipmaps; // 4 - 96
};
layout(set = 0, binding = 16, std140) uniform VoxelGIs {
diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
index 25d87ca45d..a6d65bffeb 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
@@ -7,7 +7,6 @@
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
#define NO_CHILDREN 0xFFFFFFFF
-#define GREY_VEC vec3(0.33333, 0.33333, 0.33333)
struct CellChildren {
uint children[8];
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index e4628b2d5a..9b72ccc87d 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -1153,7 +1153,7 @@ void main() {
}
#endif // !USE_LIGHTMAP
- if (scene_data.ssao_enabled) {
+ if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) {
float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
ao = min(ao, ssao);
ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect);
@@ -1223,6 +1223,12 @@ void main() {
// convert ao to direct light ao
ao = mix(1.0, ao, ao_light_affect);
+ if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) {
+ vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0);
+ ambient_light *= 1.0 - ssil.a;
+ ambient_light += ssil.rgb * albedo.rgb;
+ }
+
//this saves some VGPRs
vec3 f0 = F0(metallic, specular, albedo);
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
index be29cf4f58..0f7cd18534 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -72,6 +72,9 @@ layout(set = 0, binding = 4) uniform sampler light_projector_sampler;
//3 bits of stride
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
+#define SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO 1
+#define SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL 2
+
layout(set = 0, binding = 5, std430) restrict readonly buffer OmniLights {
LightData data[];
}
@@ -201,7 +204,7 @@ layout(set = 1, binding = 0, std140) uniform SceneData {
float z_far;
float z_near;
- bool ssao_enabled;
+ uint ss_effects_flags;
float ssao_light_affect;
float ssao_ao_affect;
bool roughness_limiter_enabled;
@@ -305,19 +308,15 @@ layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades;
struct VoxelGIData {
- mat4 xform;
- vec3 bounds;
- float dynamic_range;
+ mat4 xform; // 64 - 64
- float bias;
- float normal_bias;
- bool blend_ambient;
- uint texture_slot;
+ vec3 bounds; // 12 - 76
+ float dynamic_range; // 4 - 80
- float anisotropy_strength;
- float ambient_occlusion;
- float ambient_occlusion_size;
- uint mipmaps;
+ float bias; // 4 - 84
+ float normal_bias; // 4 - 88
+ bool blend_ambient; // 4 - 92
+ uint mipmaps; // 4 - 96
};
layout(set = 1, binding = 17, std140) uniform VoxelGIs {
@@ -327,6 +326,8 @@ voxel_gi_instances;
layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture;
+layout(set = 1, binding = 19) uniform texture2D ssil_buffer;
+
#endif
/* Set 2 Skeleton & Instancing (can change per item) */
diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl
index 78e0a85341..fde5688301 100644
--- a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl
+++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl
@@ -223,7 +223,6 @@ void main() {
blur_radius = (a * (sqrt(a2 + fh2) - a)) / (4.0f * h);
}
}
-
final_color = imageLoad(source_diffuse, ivec2((final_pos - 0.5) * pixel_size));
imageStore(blur_radius_image, ssC, vec4(blur_radius / 255.0)); //stored in r8
diff --git a/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl b/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl
index ee0db6a6f0..bdabc146d8 100644
--- a/servers/rendering/renderer_rd/shaders/ssao_downsample.glsl
+++ b/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl
@@ -42,6 +42,9 @@ layout(r16f, set = 1, binding = 0) uniform restrict writeonly image2DArray dest_
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;
+#ifdef GENERATE_FULL_MIPS
+layout(r16f, set = 2, binding = 3) uniform restrict writeonly image2DArray dest_image4;
+#endif
#endif
vec4 screen_space_to_view_space_depth(vec4 p_depth) {
@@ -150,7 +153,27 @@ void prepare_depths_and_mips(vec4 p_samples, uvec2 p_output_coord, uvec2 p_gtid)
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));
+#ifndef GENERATE_FULL_MIPS
+ }
+#else
+ depth_buffer[depth_array_index][buffer_coord.x][buffer_coord.y] = avg;
}
+ still_alive = p_gtid.x % 16 == depth_array_offset.x && depth_array_offset.y % 16 == 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 + 8];
+ float sample_10 = depth_buffer[depth_array_index][buffer_coord.x + 8][buffer_coord.y + 0];
+ float sample_11 = depth_buffer[depth_array_index][buffer_coord.x + 8][buffer_coord.y + 8];
+
+ float avg = mip_smart_average(vec4(sample_00, sample_01, sample_10, sample_11));
+ imageStore(dest_image4, ivec3(p_output_coord.x, p_output_coord.y, depth_array_index), vec4(avg));
+ }
+#endif
}
#else
#ifndef USE_HALF_BUFFERS
diff --git a/servers/rendering/renderer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/ssao.glsl
index 6e945edfcd..18cab75c3b 100644
--- a/servers/rendering/renderer_rd/shaders/ssao.glsl
+++ b/servers/rendering/renderer_rd/shaders/ssao.glsl
@@ -23,8 +23,6 @@
#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),
@@ -62,7 +60,6 @@ const int num_taps[5] = { 3, 5, 12, 0, 0 };
#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
diff --git a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl
index d9cd2b4e85..b154f5e527 100644
--- a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl
+++ b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl
@@ -128,19 +128,19 @@ void main() {
#ifdef MODE_NON_SMART
- vec2 halfPixel = params.half_screen_pixel_size * 0.5f;
+ vec2 half_pixel = params.half_screen_pixel_size * 0.5;
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;
+ vec2 center = 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;
+ vals.x = textureLod(source_ssao, vec2(uv + vec2(-half_pixel.x * 3, -half_pixel.y)), 0.0).x;
+ vals.y = textureLod(source_ssao, vec2(uv + vec2(+half_pixel.x, -half_pixel.y * 3)), 0.0).x;
+ vals.z = textureLod(source_ssao, vec2(uv + vec2(-half_pixel.x, +half_pixel.y * 3)), 0.0).x;
+ vals.w = textureLod(source_ssao, vec2(uv + vec2(+half_pixel.x * 3, +half_pixel.y)), 0.0).x;
- vec2 sampled = vec2(dot(vals, vec4(0.2)) + centre.x * 0.2, centre.y);
+ vec2 sampled = vec2(dot(vals, vec4(0.2)) + center.x * 0.2, center.y);
#else
#ifdef MODE_SMART
diff --git a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl
index 687fe1e6e2..23eba34d63 100644
--- a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl
+++ b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl
@@ -26,7 +26,7 @@
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;
+layout(set = 0, binding = 0) uniform sampler2DArray source_texture;
#else
layout(set = 0, binding = 0) uniform sampler2D source_importance;
#endif
@@ -56,11 +56,10 @@ void main() {
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));
+ vec4 vals = textureGather(source_texture, vec3(base_uv, i));
// apply the same modifications that would have been applied in the main shader
vals = params.intensity * vals;
@@ -69,8 +68,6 @@ void main() {
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)));
}
diff --git a/servers/rendering/renderer_rd/shaders/ssil.glsl b/servers/rendering/renderer_rd/shaders/ssil.glsl
new file mode 100644
index 0000000000..d1f8f42790
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssil.glsl
@@ -0,0 +1,444 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// 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
+// 2021-05-27: clayjohn: convert SSAO to SSIL
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+#[compute]
+
+#version 450
+
+#VERSION_DEFINES
+
+#define SSIL_MAIN_DISK_SAMPLE_COUNT (32)
+const vec4 sample_pattern[SSIL_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 SSIL_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 SSIL_TILT_SAMPLES_ENABLE_AT_QUALITY_PRESET (99) // to disable simply set to 99 or similar
+#define SSIL_TILT_SAMPLES_AMOUNT (0.4)
+//
+#define SSIL_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET (1) // to disable simply set to 99 or similar
+#define SSIL_HALOING_REDUCTION_AMOUNT (0.8) // values from 0.0 - 1.0, 1.0 means max weighting (will cause artifacts, 0.8 is more reasonable)
+//
+#define SSIL_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET (2)
+#define SSIL_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 SSIL_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET (1)
+//
+#define SSIL_REDUCE_RADIUS_NEAR_SCREEN_BORDER_ENABLE_AT_QUALITY_PRESET (1)
+
+#define SSIL_MAX_TAPS 32
+#define SSIL_ADAPTIVE_TAP_BASE_COUNT 5
+#define SSIL_ADAPTIVE_TAP_FLEXIBLE_COUNT (SSIL_MAX_TAPS - SSIL_ADAPTIVE_TAP_BASE_COUNT)
+#define SSIL_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(rgba16, set = 1, binding = 0) uniform restrict readonly image2DArray source_ssil;
+layout(set = 1, binding = 1) uniform sampler2D source_importance;
+layout(set = 1, binding = 2, std430) buffer Counter {
+ uint sum;
+}
+counter;
+#endif
+
+layout(rgba16, set = 2, binding = 0) uniform restrict writeonly image2D dest_image;
+layout(r8, set = 2, binding = 1) uniform image2D edges_weights_image;
+
+layout(set = 3, binding = 0) uniform sampler2D last_frame;
+layout(set = 3, binding = 1) uniform ProjectionConstants {
+ mat4 reprojection;
+}
+projection_constants;
+
+layout(push_constant, binding = 3, std430) uniform Params {
+ ivec2 screen_size;
+ int pass;
+ int quality;
+
+ vec2 half_screen_pixel_size;
+ vec2 half_screen_pixel_size_x025;
+
+ vec2 NDC_to_view_mul;
+ vec2 NDC_to_view_add;
+
+ vec2 pad2;
+ float z_near;
+ float z_far;
+
+ float radius;
+ float intensity;
+ int size_multiplier;
+ int pad;
+
+ float fade_out_mul;
+ float fade_out_add;
+ float normal_rejection_amount;
+ 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;
+
+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 - 0.05) * falloff_mult;
+}
+
+void SSIL_tap_inner(const int p_quality_level, inout vec3 r_color_sum, 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;
+ vec3 sample_normal = load_normal(ivec2(p_sampling_uv * vec2(params.screen_size)));
+
+ // convert to viewspace
+ vec3 hit_pos = NDC_to_view_space(p_sampling_uv.xy, viewspace_sample_z);
+ 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 >= SSIL_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 = SSIL_HALOING_REDUCTION_AMOUNT * reduct + (1.0 - SSIL_HALOING_REDUCTION_AMOUNT);
+ }
+
+ // Translate sampling_uv to last screen's coordinates
+ const vec4 sample_pos = projection_constants.reprojection * vec4(p_sampling_uv * 2.0 - 1.0, (viewspace_sample_z - params.z_near) / (params.z_far - params.z_near) * 2.0 - 1.0, 1.0);
+ vec2 reprojected_sampling_uv = (sample_pos.xy / sample_pos.w) * 0.5 + 0.5;
+
+ weight *= p_weight_mod;
+
+ r_obscurance_sum += obscurance * weight;
+
+ vec3 sample_color = textureLod(last_frame, reprojected_sampling_uv, 5.0).rgb;
+ // Reduce impact of fireflies by tonemapping before averaging: http://graphicrants.blogspot.com/2013/12/tone-mapping.html
+ sample_color /= (1.0 + dot(sample_color, vec3(0.299, 0.587, 0.114)));
+ r_color_sum += sample_color * obscurance * weight * mix(1.0, smoothstep(0.0, 0.1, -dot(sample_normal, normalize(hit_delta))), params.normal_rejection_amount);
+ r_weight_sum += weight;
+}
+
+void SSILTap(const int p_quality_level, inout vec3 r_color_sum, 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 < SSIL_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;
+
+ SSIL_tap_inner(p_quality_level, r_color_sum, 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 >= SSIL_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;
+
+ SSIL_tap_inner(p_quality_level, r_color_sum, 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_SSIL(out vec3 r_color, out vec4 r_edges, out float r_obscurance, 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) ? (SSIL_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 >= SSIL_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
+ vec3 color_sum = vec3(0.0);
+ 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 >= SSIL_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET)) {
+ edgesLRTB = calculate_edges(pix_z, pix_left_z, pix_right_z, pix_top_z, pix_bottom_z);
+ }
+
+ const float global_mip_offset = SSIL_DEPTH_MIPS_GLOBAL_OFFSET;
+ float mip_offset = (p_quality_level < SSIL_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 *= SSIL_TILT_SAMPLES_AMOUNT;
+
+ // standard, non-adaptive approach
+ if ((p_quality_level != 3) || p_adaptive_base) {
+ for (int i = 0; i < number_of_taps; i++) {
+ SSILTap(p_quality_level, color_sum, 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;
+
+ //Need to store obscurance from base pass
+ // load existing base values
+ vec4 base_values = imageLoad(source_ssil, ivec3(upos, params.pass));
+ weight_sum += imageLoad(edges_weights_image, ivec2(upos)).r * float(SSIL_ADAPTIVE_TAP_BASE_COUNT * 4.0);
+ color_sum += (base_values.rgb) * weight_sum;
+ obscurance_sum += (base_values.a) * 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 = SSIL_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(SSIL_MAX_TAPS, additional_samples + SSIL_ADAPTIVE_TAP_BASE_COUNT);
+
+ for (uint i = SSIL_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);
+ SSILTap(p_quality_level, color_sum, 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
+ if (p_adaptive_base) {
+ vec3 color = color_sum / weight_sum;
+
+ r_color = color;
+ r_edges = vec4(0.0);
+ r_obscurance = obscurance_sum / weight_sum;
+ r_weight = weight_sum;
+ return;
+ }
+
+ // Calculate weighted average
+ vec3 color = color_sum / weight_sum;
+ color /= 1.0 - dot(color, vec3(0.299, 0.587, 0.114));
+
+ // 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 SSIL 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 >= SSIL_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);
+ }
+
+ color = params.intensity * color;
+
+ color *= fade_out;
+
+ // outputs!
+ r_color = color;
+ 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_obscurance = clamp((obscurance_sum / weight_sum) * params.intensity, 0.0, 1.0);
+ r_weight = weight_sum;
+}
+
+void main() {
+ vec3 out_color;
+ float out_obscurance;
+ 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 SSIL_BASE
+ generate_SSIL(out_color, out_edges, out_obscurance, out_weight, uv, params.quality, true);
+
+ imageStore(dest_image, ssC, vec4(out_color, out_obscurance));
+ imageStore(edges_weights_image, ssC, vec4(out_weight / (float(SSIL_ADAPTIVE_TAP_BASE_COUNT) * 4.0)));
+#else
+ generate_SSIL(out_color, out_edges, out_obscurance, out_weight, uv, params.quality, false); // pass in quality levels
+
+ imageStore(dest_image, ssC, vec4(out_color, out_obscurance));
+ imageStore(edges_weights_image, ssC, vec4(pack_edges(out_edges)));
+#endif
+}
diff --git a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl b/servers/rendering/renderer_rd/shaders/ssil_blur.glsl
new file mode 100644
index 0000000000..11861e261f
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssil_blur.glsl
@@ -0,0 +1,124 @@
+#[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_ssil;
+
+layout(rgba16, set = 1, binding = 0) uniform restrict writeonly image2D dest_image;
+
+layout(r8, set = 2, binding = 0) uniform restrict readonly image2D source_edges;
+
+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(vec4 p_ssil_value, float p_edge_value, inout vec4 r_sum, inout float r_sum_weight) {
+ float weight = p_edge_value;
+
+ r_sum += (weight * p_ssil_value);
+ r_sum_weight += weight;
+}
+
+#ifdef MODE_WIDE
+vec4 sample_blurred_wide(ivec2 p_pos, vec2 p_coord) {
+ vec4 ssil_value = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(0, 0));
+ vec4 ssil_valueL = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(-2, 0));
+ vec4 ssil_valueT = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(0, -2));
+ vec4 ssil_valueR = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(2, 0));
+ vec4 ssil_valueB = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(0, 2));
+
+ vec4 edgesLRTB = unpack_edges(imageLoad(source_edges, p_pos).r);
+ edgesLRTB.x *= unpack_edges(imageLoad(source_edges, p_pos + ivec2(-2, 0)).r).y;
+ edgesLRTB.z *= unpack_edges(imageLoad(source_edges, p_pos + ivec2(0, -2)).r).w;
+ edgesLRTB.y *= unpack_edges(imageLoad(source_edges, p_pos + ivec2(2, 0)).r).x;
+ edgesLRTB.w *= unpack_edges(imageLoad(source_edges, p_pos + ivec2(0, 2)).r).z;
+
+ float sum_weight = 0.8;
+ vec4 sum = ssil_value * sum_weight;
+
+ add_sample(ssil_valueL, edgesLRTB.x, sum, sum_weight);
+ add_sample(ssil_valueR, edgesLRTB.y, sum, sum_weight);
+ add_sample(ssil_valueT, edgesLRTB.z, sum, sum_weight);
+ add_sample(ssil_valueB, edgesLRTB.w, sum, sum_weight);
+
+ vec4 ssil_avg = sum / sum_weight;
+
+ ssil_value = ssil_avg;
+
+ return ssil_value;
+}
+#endif
+
+#ifdef MODE_SMART
+vec4 sample_blurred(ivec2 p_pos, vec2 p_coord) {
+ vec4 vC = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(0, 0));
+ vec4 vL = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(-1, 0));
+ vec4 vT = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(0, -1));
+ vec4 vR = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(1, 0));
+ vec4 vB = textureLodOffset(source_ssil, vec2(p_coord), 0.0, ivec2(0, 1));
+
+ float packed_edges = imageLoad(source_edges, p_pos).r;
+ vec4 edgesLRTB = unpack_edges(packed_edges);
+
+ float sum_weight = 0.5;
+ vec4 sum = vC * sum_weight;
+
+ add_sample(vL, edgesLRTB.x, sum, sum_weight);
+ add_sample(vR, edgesLRTB.y, sum, sum_weight);
+ add_sample(vT, edgesLRTB.z, sum, sum_weight);
+ add_sample(vB, edgesLRTB.w, sum, sum_weight);
+
+ vec4 ssil_avg = sum / sum_weight;
+
+ vec4 ssil_value = ssil_avg;
+
+ return ssil_value;
+}
+#endif
+
+void main() {
+ // Pixel being shaded
+ ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
+
+#ifdef MODE_NON_SMART
+
+ vec2 half_pixel = params.half_screen_pixel_size * 0.5;
+
+ vec2 uv = (vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size;
+
+ vec4 centre = textureLod(source_ssil, uv, 0.0);
+
+ vec4 value = textureLod(source_ssil, vec2(uv + vec2(-half_pixel.x * 3, -half_pixel.y)), 0.0) * 0.2;
+ value += textureLod(source_ssil, vec2(uv + vec2(+half_pixel.x, -half_pixel.y * 3)), 0.0) * 0.2;
+ value += textureLod(source_ssil, vec2(uv + vec2(-half_pixel.x, +half_pixel.y * 3)), 0.0) * 0.2;
+ value += textureLod(source_ssil, vec2(uv + vec2(+half_pixel.x * 3, +half_pixel.y)), 0.0) * 0.2;
+
+ vec4 sampled = value + centre * 0.2;
+
+#else
+#ifdef MODE_SMART
+ vec4 sampled = sample_blurred(ssC, (vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size);
+#else // MODE_WIDE
+ vec4 sampled = sample_blurred_wide(ssC, (vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size);
+#endif
+#endif // MODE_NON_SMART
+ imageStore(dest_image, ssC, sampled);
+}
diff --git a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl b/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl
new file mode 100644
index 0000000000..815aa55fd4
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl
@@ -0,0 +1,124 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// 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_texture;
+#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 pad;
+}
+params;
+
+void main() {
+ // Pixel being shaded
+ ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
+
+#ifdef GENERATE_MAP
+ // importance map stuff
+ uvec2 base_position = ssC * 2;
+
+ float avg = 0.0;
+ float minV = 1.0;
+ float maxV = 0.0;
+ for (int i = 0; i < 4; i++) {
+ vec3 value_a = texelFetch(source_texture, ivec3(base_position, i), 0).rgb * params.intensity;
+ vec3 value_b = texelFetch(source_texture, ivec3(base_position, i) + ivec3(0, 1, 0), 0).rgb * params.intensity;
+ vec3 value_c = texelFetch(source_texture, ivec3(base_position, i) + ivec3(1, 0, 0), 0).rgb * params.intensity;
+ vec3 value_d = texelFetch(source_texture, ivec3(base_position, i) + ivec3(1, 1, 0), 0).rgb * params.intensity;
+
+ // Calculate luminance (black and white value)
+ float a = dot(value_a, vec3(0.2125, 0.7154, 0.0721));
+ float b = dot(value_b, vec3(0.2125, 0.7154, 0.0721));
+ float c = dot(value_c, vec3(0.2125, 0.7154, 0.0721));
+ float d = dot(value_d, vec3(0.2125, 0.7154, 0.0721));
+
+ maxV = max(maxV, max(max(a, b), max(c, d)));
+ minV = min(minV, min(min(a, b), min(c, d)));
+ }
+
+ float min_max_diff = maxV - minV;
+
+ imageStore(dest_image, ssC, vec4(pow(clamp(min_max_diff * 2.0, 0.0, 1.0), 0.6)));
+#endif
+
+#ifdef PROCESS_MAPA
+ vec2 uv = (vec2(ssC) + 0.5) * params.half_screen_pixel_size * 2.0;
+
+ float centre = textureLod(source_importance, uv, 0.0).x;
+
+ 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/ssil_interleave.glsl b/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl
new file mode 100644
index 0000000000..8a7a5ae4fd
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl
@@ -0,0 +1,102 @@
+#[compute]
+
+#version 450
+
+#VERSION_DEFINES
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+layout(rgba16, set = 0, binding = 0) uniform restrict writeonly image2D dest_image;
+layout(set = 1, binding = 0) uniform sampler2DArray source_texture;
+layout(r8, set = 2, binding = 0) uniform restrict readonly image2DArray source_edges;
+
+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
+ 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
+
+ vec4 color = texelFetch(source_texture, ivec3(pix_pos / uvec2(params.size_modifier), index_center), 0);
+
+ vec4 edgesLRTB = unpack_edges(imageLoad(source_edges, ivec3(pix_pos / uvec2(params.size_modifier), index_center)).r);
+
+ // 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;
+ vec4 color_horizontal = textureLod(source_texture, vec3(uv_horizontal, index_horizontal), 0.0);
+ vec2 uv_vertical = (gl_GlobalInvocationID.xy + vec2(0.5) + vec2(0.5 - fmx, fmy - 0.5 + fmye)) * params.pixel_size;
+ vec4 color_vertical = textureLod(source_texture, vec3(uv_vertical, index_vertical), 0.0);
+ vec2 uv_diagonal = (gl_GlobalInvocationID.xy + vec2(0.5) + vec2(fmx - 0.5 + fmxe, fmy - 0.5 + fmye)) * params.pixel_size;
+ vec4 color_diagonal = textureLod(source_texture, vec3(uv_diagonal, index_diagonal), 0.0);
+
+ // 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));
+ color += color_horizontal * blendWeights.y;
+ color += color_vertical * blendWeights.z;
+ color += color_diagonal * blendWeights.w;
+ color /= blendWeightsSum;
+
+ imageStore(dest_image, ivec2(gl_GlobalInvocationID.xy), color);
+#else // !MODE_SMART
+
+ vec2 uv = (gl_GlobalInvocationID.xy + vec2(0.5)) * params.pixel_size;
+#ifdef MODE_HALF
+ vec4 a = textureLod(source_texture, vec3(uv, 0), 0.0);
+ vec4 d = textureLod(source_texture, vec3(uv, 3), 0.0);
+ vec4 avg = (a + d) * 0.5;
+
+#else
+ vec4 a = textureLod(source_texture, vec3(uv, 0), 0.0);
+ vec4 b = textureLod(source_texture, vec3(uv, 1), 0.0);
+ vec4 c = textureLod(source_texture, vec3(uv, 2), 0.0);
+ vec4 d = textureLod(source_texture, vec3(uv, 3), 0.0);
+ vec4 avg = (a + b + c + d) * 0.25;
+
+#endif
+ imageStore(dest_image, ivec2(gl_GlobalInvocationID.xy), avg);
+#endif
+}
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
index 747f88960c..7c8d4f7f99 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
@@ -76,19 +76,15 @@ layout(set = 0, binding = 10) uniform sampler shadow_sampler;
#define MAX_VOXEL_GI_INSTANCES 8
struct VoxelGIData {
- mat4 xform;
- vec3 bounds;
- float dynamic_range;
+ mat4 xform; // 64 - 64
- float bias;
- float normal_bias;
- bool blend_ambient;
- uint texture_slot;
+ vec3 bounds; // 12 - 76
+ float dynamic_range; // 4 - 80
- float anisotropy_strength;
- float ambient_occlusion;
- float ambient_occlusion_size;
- uint mipmaps;
+ float bias; // 4 - 84
+ float normal_bias; // 4 - 88
+ bool blend_ambient; // 4 - 92
+ uint mipmaps; // 4 - 96
};
layout(set = 0, binding = 11, std140) uniform VoxelGIs {
@@ -581,16 +577,29 @@ void main() {
if (spot_lights.data[light_index].shadow_enabled) {
//has shadow
- vec4 v = vec4(view_pos, 1.0);
+ vec4 uv_rect = spot_lights.data[light_index].atlas_rect;
+ vec2 flip_offset = spot_lights.data[light_index].direction.xy;
- vec4 splane = (spot_lights.data[light_index].shadow_matrix * v);
- splane /= splane.w;
+ vec3 local_vert = (spot_lights.data[light_index].shadow_matrix * vec4(view_pos, 1.0)).xyz;
- float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r;
+ float shadow_len = length(local_vert); //need to remember shadow len from here
+ vec3 shadow_sample = normalize(local_vert);
- shadow_attenuation = exp(min(0.0, (depth - splane.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade);
- }
+ if (shadow_sample.z >= 0.0) {
+ uv_rect.xy += flip_offset;
+ }
+ shadow_sample.z = 1.0 + abs(shadow_sample.z);
+ vec3 pos = vec3(shadow_sample.xy / shadow_sample.z, shadow_len - spot_lights.data[light_index].shadow_bias);
+ pos.z *= spot_lights.data[light_index].inv_radius;
+
+ pos.xy = pos.xy * 0.5 + 0.5;
+ pos.xy = uv_rect.xy + pos.xy * uv_rect.zw;
+
+ float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r;
+
+ shadow_attenuation = exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade);
+ }
total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g);
}
}
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
index 779f04ed35..73a97d9df1 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
@@ -13,7 +13,6 @@ layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
#ifndef MODE_DYNAMIC
#define NO_CHILDREN 0xFFFFFFFF
-#define GREY_VEC vec3(0.33333, 0.33333, 0.33333)
struct CellChildren {
uint children[8];
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
index 281c496df3..3f3437f527 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
@@ -90,66 +90,10 @@ void main() {
#endif
#ifdef MODE_DEBUG_LIGHT
-
-#ifdef USE_ANISOTROPY
-
-#define POS_X 0
-#define POS_Y 1
-#define POS_Z 2
-#define NEG_X 3
-#define NEG_Y 4
-#define NEG_Z 5
-
- const uint triangle_aniso[12] = uint[](
- NEG_X,
- NEG_Z,
- NEG_Y,
- NEG_Z,
- NEG_X,
- NEG_Y,
- POS_Z,
- POS_X,
- POS_X,
- POS_Y,
- POS_Y,
- POS_Z);
-
- color_interp.xyz = texelFetch(sampler3D(color_tex, tex_sampler), ivec3(posu), int(params.level)).xyz * params.dynamic_range;
- vec3 aniso_pos = texelFetch(sampler3D(aniso_pos_tex, tex_sampler), ivec3(posu), int(params.level)).xyz;
- vec3 aniso_neg = texelFetch(sampler3D(aniso_neg_tex, tex_sampler), ivec3(posu), int(params.level)).xyz;
- uint side = triangle_aniso[gl_VertexIndex / 3];
-
- float strength = 0.0;
- switch (side) {
- case POS_X:
- strength = aniso_pos.x;
- break;
- case POS_Y:
- strength = aniso_pos.y;
- break;
- case POS_Z:
- strength = aniso_pos.z;
- break;
- case NEG_X:
- strength = aniso_neg.x;
- break;
- case NEG_Y:
- strength = aniso_neg.y;
- break;
- case NEG_Z:
- strength = aniso_neg.z;
- break;
- }
-
- color_interp.xyz *= strength;
-
-#else
color_interp = texelFetch(sampler3D(color_tex, tex_sampler), ivec3(posu), int(params.level));
color_interp.xyz *params.dynamic_range;
-
#endif
-#endif
float scale = (1 << params.level);
gl_Position = params.projection * vec4((vec3(posu) + vertex) * scale, 1.0);
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl
index e20b3f680d..3bb4421646 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl
+++ b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl
@@ -6,10 +6,9 @@
layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
-#define MAX_DISTANCE 100000
+#define MAX_DISTANCE 100000.0
#define NO_CHILDREN 0xFFFFFFFF
-#define GREY_VEC vec3(0.33333, 0.33333, 0.33333)
struct CellChildren {
uint children[8];
@@ -44,7 +43,7 @@ params;
void main() {
vec3 pos = vec3(gl_GlobalInvocationID);
- float closest_dist = 100000.0;
+ float closest_dist = MAX_DISTANCE;
for (uint i = params.offset; i < params.end; i++) {
vec3 posu = vec3(uvec3(cell_data.data[i].position & 0x7FF, (cell_data.data[i].position >> 11) & 0x3FF, cell_data.data[i].position >> 21));
diff --git a/servers/rendering/renderer_scene.cpp b/servers/rendering/renderer_scene.cpp
index dd544d4f3f..b3fdd88626 100644
--- a/servers/rendering/renderer_scene.cpp
+++ b/servers/rendering/renderer_scene.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
index 02c845581c..f4aca8dce2 100644
--- a/servers/rendering/renderer_scene.h
+++ b/servers/rendering/renderer_scene.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -143,9 +143,11 @@ public:
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_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) = 0;
+ virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 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, float p_bounce_feedback, 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;
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 5b834db178..1f72b23f8a 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index e51a1fc02e..6d5b714782 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1108,6 +1108,9 @@ public:
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)
+ PASS6(environment_set_ssil, RID, bool, float, float, float, float)
+ PASS6(environment_set_ssil_quality, RS::EnvironmentSSILQuality, 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)
diff --git a/servers/rendering/renderer_scene_occlusion_cull.cpp b/servers/rendering/renderer_scene_occlusion_cull.cpp
index 1b8aea36d7..bda0950097 100644
--- a/servers/rendering/renderer_scene_occlusion_cull.cpp
+++ b/servers/rendering/renderer_scene_occlusion_cull.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h
index 4e4b1b94db..48412dab68 100644
--- a/servers/rendering/renderer_scene_occlusion_cull.h
+++ b/servers/rendering/renderer_scene_occlusion_cull.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp
index 38d1218dee..c802f72fdf 100644
--- a/servers/rendering/renderer_scene_render.cpp
+++ b/servers/rendering/renderer_scene_render.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index 0d71ea22da..3c4582eab8 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -134,9 +134,11 @@ public:
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_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) = 0;
+ virtual void environment_set_ssil_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 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, float p_bounce_feedback, 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;
diff --git a/servers/rendering/renderer_storage.cpp b/servers/rendering/renderer_storage.cpp
index aa005fac0a..56409ae187 100644
--- a/servers/rendering/renderer_storage.cpp
+++ b/servers/rendering/renderer_storage.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h
index 8926bf24aa..056fecd020 100644
--- a/servers/rendering/renderer_storage.h
+++ b/servers/rendering/renderer_storage.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_thread_pool.cpp b/servers/rendering/renderer_thread_pool.cpp
index 98050dd508..ddf1d1bd00 100644
--- a/servers/rendering/renderer_thread_pool.cpp
+++ b/servers/rendering/renderer_thread_pool.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_thread_pool.h b/servers/rendering/renderer_thread_pool.h
index ae25415a0d..4626490d32 100644
--- a/servers/rendering/renderer_thread_pool.h
+++ b/servers/rendering/renderer_thread_pool.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index eddf5bf53d..395e8d9583 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index 5bb4dbbc6f..0db8b76dd9 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index dcbc5f5c8e..cc2856f159 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -98,10 +98,10 @@ RID RenderingDevice::_texture_create_shared(const Ref<RDTextureView> &p_view, RI
return texture_create_shared(p_view->base, p_with_texture);
}
-RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) {
+RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps, TextureSliceType p_slice_type) {
ERR_FAIL_COND_V(p_view.is_null(), RID());
- return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type);
+ return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_mipmaps, p_slice_type);
}
RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments, uint32_t p_view_count) {
@@ -185,9 +185,13 @@ Ref<RDShaderSPIRV> RenderingDevice::_shader_compile_spirv_from_source(const Ref<
String error;
ShaderStage stage = ShaderStage(i);
- Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache);
- bytecode->set_stage_bytecode(stage, spirv);
- bytecode->set_stage_compile_error(stage, error);
+ String source = p_source->get_stage_source(stage);
+
+ if (!source.is_empty()) {
+ Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, source, p_source->get_language(), &error, p_allow_cache);
+ bytecode->set_stage_bytecode(stage, spirv);
+ bytecode->set_stage_compile_error(stage, error);
+ }
}
return bytecode;
}
@@ -201,7 +205,7 @@ Vector<uint8_t> RenderingDevice::_shader_compile_binary_from_spirv(const Ref<RDS
ShaderStageSPIRVData sd;
sd.shader_stage = stage;
String error = p_spirv->get_stage_compile_error(stage);
- ERR_FAIL_COND_V_MSG(error != String(), Vector<uint8_t>(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
+ ERR_FAIL_COND_V_MSG(!error.is_empty(), Vector<uint8_t>(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
sd.spir_v = p_spirv->get_stage_bytecode(stage);
if (sd.spir_v.is_empty()) {
continue;
@@ -221,7 +225,7 @@ RID RenderingDevice::_shader_create_from_spirv(const Ref<RDShaderSPIRV> &p_spirv
ShaderStageSPIRVData sd;
sd.shader_stage = stage;
String error = p_spirv->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.");
+ ERR_FAIL_COND_V_MSG(!error.is_empty(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
sd.spir_v = p_spirv->get_stage_bytecode(stage);
if (sd.spir_v.is_empty()) {
continue;
@@ -360,7 +364,7 @@ void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, cons
void RenderingDevice::_bind_methods() {
ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared);
- ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D));
+ ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "mipmaps", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(1), DEFVAL(TEXTURE_SLICE_2D));
ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "post_barrier"), &RenderingDevice::texture_update, DEFVAL(BARRIER_MASK_ALL));
ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data);
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 563a80c12c..737c782776 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -505,7 +505,7 @@ public:
TEXTURE_SLICE_2D_ARRAY,
};
- virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0;
+ virtual RID texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D) = 0;
virtual Error texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, uint32_t p_post_barrier = BARRIER_MASK_ALL) = 0;
virtual Vector<uint8_t> texture_get_data(RID p_texture, uint32_t p_layer) = 0; // CPU textures will return immediately, while GPU textures will most likely force a flush
@@ -1210,7 +1210,7 @@ protected:
//binders to script API
RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array());
RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture);
- RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
+ RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, uint32_t p_mipmaps = 1, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments, uint32_t p_view_count);
FramebufferFormatID _framebuffer_format_create_multipass(const TypedArray<RDAttachmentFormat> &p_attachments, const TypedArray<RDFramebufferPass> &p_passes, uint32_t p_view_count);
diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp
index a21f28989b..19cde610ba 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -80,7 +80,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
}
}
- if (base_error != String()) {
+ if (!base_error.is_empty()) {
break;
}
}
@@ -89,7 +89,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
}
}
- if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") {
+ if (stage == RD::SHADER_STAGE_MAX && !line.strip_edges().is_empty()) {
line = line.strip_edges();
if (line.begins_with("//") || line.begins_with("/*")) {
continue; //assuming comment (single line)
@@ -98,7 +98,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
if (reading_versions) {
String l = line.strip_edges();
- if (l != "") {
+ if (!l.is_empty()) {
if (l.find("=") == -1) {
base_error = "Missing `=` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
break;
@@ -124,7 +124,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
version_texts[version] = define + "\n" + p_defines;
}
} else {
- if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") {
+ if (stage == RD::SHADER_STAGE_MAX && !line.strip_edges().is_empty()) {
base_error = "Text was found that does not belong to a valid section: " + line;
break;
}
@@ -140,7 +140,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
}
include = include.substr(1, include.length() - 2).strip_edges();
String include_text = p_include_func(include, p_include_func_userdata);
- if (include_text != String()) {
+ if (!include_text.is_empty()) {
stage_code[stage] += "\n" + include_text + "\n";
} else {
base_error = "#include failed for file '" + include + "'";
@@ -158,7 +158,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
Ref<RDShaderFile> shader_file;
shader_file.instantiate();
- if (base_error == "") {
+ if (base_error.is_empty()) {
if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) {
ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present.");
}
@@ -177,14 +177,14 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String
for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
String code = stage_code[i];
- if (code == String()) {
+ if (code.is_empty()) {
continue;
}
code = code.replace("VERSION_DEFINES", E.value);
String error;
Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_spirv_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false);
bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv);
- if (error != "") {
+ if (!error.is_empty()) {
error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n";
Vector<String> sclines = code.split("\n");
for (int j = 0; j < sclines.size(); j++) {
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
index 2cf7821668..b07857364b 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -368,13 +368,13 @@ public:
}
void print_errors(const String &p_file) {
- if (base_error != "") {
+ if (!base_error.is_empty()) {
ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error);
} else {
for (KeyValue<StringName, Ref<RDShaderSPIRV>> &E : versions) {
for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
String error = E.value->get_stage_compile_error(RD::ShaderStage(i));
- if (error != String()) {
+ if (!error.is_empty()) {
static const char *stage_str[RD::SHADER_STAGE_MAX] = {
"vertex",
"fragment",
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 2ce9a20b6b..e60e507f87 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index b50631bb21..c4a6494da9 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -626,6 +626,9 @@ public:
FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, float, float)
FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float)
+ FUNC6(environment_set_ssil, RID, bool, float, float, float, float)
+ FUNC6(environment_set_ssil_quality, EnvironmentSSILQuality, bool, float, int, float, float)
+
FUNC11(environment_set_glow, RID, bool, Vector<float>, float, float, float, float, EnvironmentGlowBlendMode, float, float, float)
FUNC1(environment_glow_set_use_bicubic_upscale, bool)
FUNC1(environment_glow_set_use_high_quality, bool)
diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp
index 2dda506bac..b8b06b5eea 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h
index 63755e6125..4351830a5f 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 50719ecfc3..5d420ba48d 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -88,7 +88,8 @@ String ShaderLanguage::get_operator_text(Operator p_op) {
"--",
"()",
"construct",
- "index" };
+ "index",
+ "empty" };
return op_names[p_op];
}
@@ -203,7 +204,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"HINT_WHITE_TEXTURE",
"HINT_BLACK_TEXTURE",
"HINT_NORMAL_TEXTURE",
- "HINT_ANISO_TEXTURE",
+ "HINT_ANISOTROPY_TEXTURE",
"HINT_ALBEDO_TEXTURE",
"HINT_BLACK_ALBEDO_TEXTURE",
"HINT_COLOR",
@@ -213,8 +214,8 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"FILTER_LINEAR",
"FILTER_NEAREST_MIPMAP",
"FILTER_LINEAR_MIPMAP",
- "FILTER_NEAREST_MIPMAP_ANISO",
- "FILTER_LINEAR_MIPMAP_ANISO",
+ "FILTER_NEAREST_MIPMAP_ANISOTROPIC",
+ "FILTER_LINEAR_MIPMAP_ANISOTROPIC",
"REPEAT_ENABLE",
"REPEAT_DISABLE",
"SHADER_TYPE",
@@ -225,7 +226,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_FLOAT_CONSTANT) {
+ if (p_token.is_integer_constant() || p_token.type == TK_FLOAT_CONSTANT) {
name += "(" + rtos(p_token.constant) + ")";
} else if (p_token.type == TK_IDENTIFIER) {
name += "(" + String(p_token.text) + ")";
@@ -317,7 +318,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_HINT_ROUGHNESS_B, "hint_roughness_b" },
{ TK_HINT_ROUGHNESS_A, "hint_roughness_a" },
{ TK_HINT_ROUGHNESS_GRAY, "hint_roughness_gray" },
- { TK_HINT_ANISO_TEXTURE, "hint_aniso" },
+ { TK_HINT_ANISOTROPY_TEXTURE, "hint_anisotropy" },
{ TK_HINT_ALBEDO_TEXTURE, "hint_albedo" },
{ TK_HINT_BLACK_ALBEDO_TEXTURE, "hint_black_albedo" },
{ TK_HINT_COLOR, "hint_color" },
@@ -327,8 +328,8 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_FILTER_LINEAR, "filter_linear" },
{ TK_FILTER_NEAREST_MIPMAP, "filter_nearest_mipmap" },
{ TK_FILTER_LINEAR_MIPMAP, "filter_linear_mipmap" },
- { TK_FILTER_NEAREST_MIPMAP_ANISO, "filter_nearest_mipmap_aniso" },
- { TK_FILTER_LINEAR_MIPMAP_ANISO, "filter_linear_mipmap_aniso" },
+ { TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC, "filter_nearest_mipmap_anisotropic" },
+ { TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC, "filter_linear_mipmap_anisotropic" },
{ TK_REPEAT_ENABLE, "repeat_enable" },
{ TK_REPEAT_DISABLE, "repeat_disable" },
{ TK_SHADER_TYPE, "shader_type" },
@@ -474,6 +475,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
case ':':
return _make_token(TK_COLON);
case '^':
+ if (GETCHAR(0) == '=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_BIT_XOR);
+ }
return _make_token(TK_OP_BIT_XOR);
case '~':
return _make_token(TK_OP_BIT_INVERT);
@@ -540,63 +545,113 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
if (_is_number(GETCHAR(0)) || (GETCHAR(0) == '.' && _is_number(GETCHAR(1)))) {
// parse number
+ bool hexa_found = false;
bool period_found = false;
bool exponent_found = false;
- bool hexa_found = false;
- bool sign_found = false;
bool float_suffix_found = false;
+ bool uint_suffix_found = false;
+ bool end_suffix_found = false;
+
+ enum {
+ CASE_ALL,
+ CASE_HEXA_PERIOD,
+ CASE_EXPONENT,
+ CASE_SIGN_AFTER_EXPONENT,
+ CASE_NONE,
+ CASE_MAX,
+ } lut_case = CASE_ALL;
+
+ static bool suffix_lut[CASE_MAX][127];
+
+ if (!is_const_suffix_lut_initialized) {
+ is_const_suffix_lut_initialized = true;
+
+ for (int i = 0; i < 127; i++) {
+ char t = char(i);
+
+ suffix_lut[CASE_ALL][i] = t == '.' || t == 'x' || t == 'e' || t == 'f' || t == 'u' || t == '-' || t == '+';
+ suffix_lut[CASE_HEXA_PERIOD][i] = t == 'e' || t == 'f';
+ suffix_lut[CASE_EXPONENT][i] = t == 'f' || t == '-' || t == '+';
+ suffix_lut[CASE_SIGN_AFTER_EXPONENT][i] = t == 'f';
+ suffix_lut[CASE_NONE][i] = false;
+ }
+ }
String str;
int i = 0;
while (true) {
- if (GETCHAR(i) == '.') {
- if (period_found || exponent_found || hexa_found || float_suffix_found) {
- return _make_token(TK_ERROR, "Invalid numeric constant");
- }
- period_found = true;
- } else if (GETCHAR(i) == 'x') {
- if (hexa_found || str.length() != 1 || str[0] != '0') {
- return _make_token(TK_ERROR, "Invalid numeric constant");
+ const char32_t symbol = String::char_lowercase(GETCHAR(i));
+ bool error = false;
+
+ if (_is_number(symbol)) {
+ if (end_suffix_found) {
+ error = true;
}
- hexa_found = true;
- } else if (GETCHAR(i) == 'e' && !hexa_found) {
- if (exponent_found || float_suffix_found) {
- return _make_token(TK_ERROR, "Invalid numeric constant");
+ } else {
+ if (symbol < 0x7F && suffix_lut[lut_case][symbol]) {
+ if (symbol == 'x') {
+ hexa_found = true;
+ lut_case = CASE_HEXA_PERIOD;
+ } else if (symbol == '.') {
+ period_found = true;
+ lut_case = CASE_HEXA_PERIOD;
+ } else if (symbol == 'e' && !hexa_found) {
+ exponent_found = true;
+ lut_case = CASE_EXPONENT;
+ } else if (symbol == 'f' && !hexa_found) {
+ if (!period_found && !exponent_found) {
+ error = true;
+ }
+ float_suffix_found = true;
+ end_suffix_found = true;
+ lut_case = CASE_NONE;
+ } else if (symbol == 'u') {
+ uint_suffix_found = true;
+ end_suffix_found = true;
+ lut_case = CASE_NONE;
+ } else if (symbol == '-' || symbol == '+') {
+ if (exponent_found) {
+ lut_case = CASE_SIGN_AFTER_EXPONENT;
+ } else {
+ break;
+ }
+ }
+ } else if (!hexa_found || !_is_hex(symbol)) {
+ if (_is_text_char(symbol)) {
+ error = true;
+ } else {
+ break;
+ }
}
- exponent_found = true;
- } else if (GETCHAR(i) == 'f' && !hexa_found) {
- if (exponent_found) {
- return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
+
+ if (error) {
+ if (hexa_found) {
+ return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant");
}
- float_suffix_found = true;
- } else if (_is_number(GETCHAR(i))) {
- if (float_suffix_found) {
- return _make_token(TK_ERROR, "Invalid numeric constant");
+ if (period_found || exponent_found || float_suffix_found) {
+ return _make_token(TK_ERROR, "Invalid (float) numeric constant");
}
- } else if (hexa_found && _is_hex(GETCHAR(i))) {
- } else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
- if (sign_found) {
- return _make_token(TK_ERROR, "Invalid numeric constant");
+ if (uint_suffix_found) {
+ return _make_token(TK_ERROR, "Invalid (unsigned integer) numeric constant");
}
- sign_found = true;
- } else {
- break;
+ return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
}
-
- str += char32_t(GETCHAR(i));
+ str += symbol;
i++;
}
char32_t last_char = str[str.length() - 1];
- if (hexa_found) {
- //integer(hex)
+ if (hexa_found) { // Integer(hex)
if (str.size() > 11 || !str.is_valid_hex_number(true)) { // > 0xFFFFFFFF
return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant");
}
- } else if (period_found || exponent_found || float_suffix_found) {
- //floats
+ } else if (period_found || exponent_found || float_suffix_found) { // Float
+ if (exponent_found && (!_is_number(last_char) && last_char != 'f')) { // checks for eg: "2E", "2E-", "2E+"
+ return _make_token(TK_ERROR, "Invalid (float) numeric constant");
+ }
if (period_found) {
if (float_suffix_found) {
//checks for eg "1.f" or "1.99f" notations
@@ -617,22 +672,28 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
}
if (float_suffix_found) {
- //strip the suffix
+ // Strip the suffix.
str = str.left(str.length() - 1);
- //compensate reading cursor position
+ // Compensate reading cursor position.
char_idx += 1;
}
if (!str.is_valid_float()) {
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
}
- } else {
- //integers
- if (!_is_number(last_char)) {
- return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
+ } else { // Integer
+ if (uint_suffix_found) {
+ // Strip the suffix.
+ str = str.left(str.length() - 1);
+ // Compensate reading cursor position.
+ char_idx += 1;
}
if (!str.is_valid_int()) {
- return _make_token(TK_ERROR, "Invalid numeric constant");
+ if (uint_suffix_found) {
+ return _make_token(TK_ERROR, "Invalid (unsigned integer) numeric constant");
+ } else {
+ return _make_token(TK_ERROR, "Invalid (integer) numeric constant");
+ }
}
}
@@ -640,6 +701,8 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
Token tk;
if (period_found || exponent_found || float_suffix_found) {
tk.type = TK_FLOAT_CONSTANT;
+ } else if (uint_suffix_found) {
+ tk.type = TK_UINT_CONSTANT;
} else {
tk.type = TK_INT_CONSTANT;
}
@@ -909,10 +972,10 @@ void ShaderLanguage::clear() {
completion_type = COMPLETION_NONE;
completion_block = nullptr;
completion_function = StringName();
- completion_class = SubClassTag::TAG_GLOBAL;
+ completion_class = TAG_GLOBAL;
completion_struct = StringName();
-
- unknown_varying_usages.clear();
+ completion_base = TYPE_VOID;
+ completion_base_array = false;
#ifdef DEBUG_ENABLED
used_constants.clear();
@@ -2654,6 +2717,8 @@ const ShaderLanguage::BuiltinFuncConstArgs ShaderLanguage::builtin_func_const_ar
{ nullptr, 0, 0, 0 }
};
+bool ShaderLanguage::is_const_suffix_lut_initialized = false;
+
bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionInfo &p_function_info, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) {
ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false);
@@ -2994,7 +3059,7 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
}
FunctionNode *pfunc = shader->functions[i].function;
- if (arg_list == "") {
+ if (arg_list.is_empty()) {
for (int j = 0; j < pfunc->arguments.size(); j++) {
if (j > 0) {
arg_list += ", ";
@@ -3230,6 +3295,10 @@ bool ShaderLanguage::is_token_operator_assign(TokenType p_type) {
p_type == TK_OP_ASSIGN_BIT_XOR);
}
+bool ShaderLanguage::is_token_hint(TokenType p_type) {
+ return int(p_type) > int(TK_RENDER_MODE) && int(p_type) < int(TK_SHADER_TYPE);
+}
+
bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value) {
if (p_constant->datatype == p_to_type) {
if (p_value) {
@@ -3797,55 +3866,77 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
return pi;
}
-uint32_t ShaderLanguage::get_type_size(DataType p_type) {
+uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) {
switch (p_type) {
case TYPE_VOID:
return 0;
case TYPE_BOOL:
- case TYPE_INT:
- case TYPE_UINT:
- case TYPE_FLOAT:
return 4;
case TYPE_BVEC2:
- case TYPE_IVEC2:
- case TYPE_UVEC2:
- case TYPE_VEC2:
return 8;
case TYPE_BVEC3:
- case TYPE_IVEC3:
- case TYPE_UVEC3:
- case TYPE_VEC3:
return 12;
case TYPE_BVEC4:
+ return 16;
+ case TYPE_INT:
+ return 4;
+ case TYPE_IVEC2:
+ return 8;
+ case TYPE_IVEC3:
+ return 12;
case TYPE_IVEC4:
+ return 16;
+ case TYPE_UINT:
+ return 4;
+ case TYPE_UVEC2:
+ return 8;
+ case TYPE_UVEC3:
+ return 12;
case TYPE_UVEC4:
+ return 16;
+ case TYPE_FLOAT:
+ return 4;
+ case TYPE_VEC2:
+ return 8;
+ case TYPE_VEC3:
+ return 12;
case TYPE_VEC4:
return 16;
case TYPE_MAT2:
- return 8;
+ return 32; // 4 * 4 + 4 * 4
case TYPE_MAT3:
- return 12;
+ return 48; // 4 * 4 + 4 * 4 + 4 * 4
case TYPE_MAT4:
- return 16;
+ return 64;
case TYPE_SAMPLER2D:
+ return 16;
case TYPE_ISAMPLER2D:
+ return 16;
case TYPE_USAMPLER2D:
+ return 16;
case TYPE_SAMPLER2DARRAY:
+ return 16;
case TYPE_ISAMPLER2DARRAY:
+ return 16;
case TYPE_USAMPLER2DARRAY:
+ return 16;
case TYPE_SAMPLER3D:
+ return 16;
case TYPE_ISAMPLER3D:
+ return 16;
case TYPE_USAMPLER3D:
+ return 16;
case TYPE_SAMPLERCUBE:
+ return 16;
case TYPE_SAMPLERCUBEARRAY:
- return 4; //not really, but useful for indices
+ return 16;
case TYPE_STRUCT:
- // FIXME: Implement.
- return 0;
- case ShaderLanguage::TYPE_MAX:
return 0;
+ case TYPE_MAX: {
+ ERR_FAIL_V(0);
+ };
}
- return 0;
+ ERR_FAIL_V(0);
}
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
@@ -4051,43 +4142,6 @@ bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, St
return true;
}
-bool ShaderLanguage::_validate_varying_using(ShaderNode::Varying &p_varying, String *r_message) {
- switch (p_varying.stage) {
- case ShaderNode::Varying::STAGE_UNKNOWN:
- VaryingUsage usage;
- usage.var = &p_varying;
- usage.line = tk_line;
- unknown_varying_usages.push_back(usage);
- break;
- case ShaderNode::Varying::STAGE_VERTEX:
- if (current_function == varying_function_names.fragment || current_function == varying_function_names.light) {
- p_varying.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT;
- }
- break;
- case ShaderNode::Varying::STAGE_FRAGMENT:
- if (current_function == varying_function_names.light) {
- p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT;
- }
- break;
- default:
- break;
- }
- return true;
-}
-
-bool ShaderLanguage::_check_varying_usages(int *r_error_line, String *r_error_message) const {
- for (const List<ShaderLanguage::VaryingUsage>::Element *E = unknown_varying_usages.front(); E; E = E->next()) {
- ShaderNode::Varying::Stage stage = E->get().var->stage;
- if (stage != ShaderNode::Varying::STAGE_UNKNOWN && stage != ShaderNode::Varying::STAGE_VERTEX && stage != ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT) {
- *r_error_line = E->get().line;
- *r_error_message = RTR("Fragment-stage varying could not been accessed in custom function!");
- return false;
- }
- }
-
- return true;
-}
-
bool ShaderLanguage::_check_node_constness(const Node *p_node) const {
switch (p_node->type) {
case Node::TYPE_OPERATOR: {
@@ -4293,7 +4347,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_size(BlockNode *p_block, cons
return n;
}
-Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
+Error ShaderLanguage::_parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info) {
if (r_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
@@ -4303,9 +4357,9 @@ Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
int array_size = 0;
- if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
+ if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) {
_set_tkpos(pos);
- Node *n = _parse_array_size(nullptr, FunctionInfo(), array_size);
+ Node *n = _parse_array_size(nullptr, p_function_info, array_size);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -4328,27 +4382,28 @@ Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
return OK;
}
-Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, ArrayDeclarationNode *p_node, ArrayDeclarationNode::Declaration *p_decl, int &r_array_size, bool &r_is_unknown_size) {
+Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size) {
TkPos pos = _get_tkpos();
Token tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
r_is_unknown_size = true;
} else {
- if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
+ int size = 0;
+ if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) {
_set_tkpos(pos);
int array_size = 0;
Node *n = _parse_array_size(p_block, p_function_info, array_size);
if (!n) {
return ERR_PARSE_ERROR;
}
- p_decl->size = array_size;
- p_node->size_expression = n;
+ size = array_size;
+ r_size_expression = n;
} else if (((int)tk.constant) > 0) {
- p_decl->size = (uint32_t)tk.constant;
+ size = (uint32_t)tk.constant;
}
- if (p_decl->size <= 0) {
+ if (size <= 0) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
}
@@ -4359,7 +4414,7 @@ Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const Function
return ERR_PARSE_ERROR;
}
- r_array_size = p_decl->size;
+ r_array_size = size;
}
return OK;
@@ -4669,6 +4724,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
constant->datatype = TYPE_INT;
expr = constant;
+ } else if (tk.type == TK_UINT_CONSTANT) {
+ ConstantNode *constant = alloc_node<ConstantNode>();
+ ConstantNode::Value v;
+ v.uint = tk.constant;
+ constant->values.push_back(v);
+ constant->datatype = TYPE_UINT;
+ expr = constant;
+
} else if (tk.type == TK_TRUE) {
//handle true constant
ConstantNode *constant = alloc_node<ConstantNode>();
@@ -4770,11 +4833,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (shader->structs.has(identifier)) {
pstruct = shader->structs[identifier].shader_struct;
-#ifdef DEBUG_ENABLED
- if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(identifier)) {
- used_structs[identifier].used = true;
- }
-#endif // DEBUG_ENABLED
struct_init = true;
}
@@ -4916,55 +4974,104 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
for (int i = 0; i < call_function->arguments.size(); i++) {
int argidx = i + 1;
if (argidx < func->arguments.size()) {
- if (call_function->arguments[i].is_const || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_OUT || call_function->arguments[i].qualifier == ArgumentQualifier::ARGUMENT_QUALIFIER_INOUT) {
- bool error = false;
- Node *n = func->arguments[argidx];
- if (n->type == Node::TYPE_CONSTANT || n->type == Node::TYPE_OPERATOR) {
- if (!call_function->arguments[i].is_const) {
+ bool error = false;
+ Node *n = func->arguments[argidx];
+ ArgumentQualifier arg_qual = call_function->arguments[i].qualifier;
+ bool is_out_arg = arg_qual != ArgumentQualifier::ARGUMENT_QUALIFIER_IN;
+
+ if (n->type == Node::TYPE_VARIABLE || n->type == Node::TYPE_ARRAY) {
+ StringName varname;
+
+ if (n->type == Node::TYPE_VARIABLE) {
+ VariableNode *vn = static_cast<VariableNode *>(n);
+ varname = vn->name;
+ } else { // TYPE_ARRAY
+ ArrayNode *an = static_cast<ArrayNode *>(n);
+ varname = an->name;
+ }
+
+ if (shader->varyings.has(varname)) {
+ switch (shader->varyings[varname].stage) {
+ case ShaderNode::Varying::STAGE_UNKNOWN: {
+ _set_error(vformat("Varying '%s' must be assigned in the vertex or fragment function first!", varname));
+ return nullptr;
+ }
+ case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT:
+ [[fallthrough]];
+ case ShaderNode::Varying::STAGE_VERTEX:
+ if (is_out_arg && current_function != varying_function_names.vertex) { // inout/out
+ error = true;
+ }
+ break;
+ case ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT:
+ [[fallthrough]];
+ case ShaderNode::Varying::STAGE_FRAGMENT:
+ if (!is_out_arg) {
+ if (current_function != varying_function_names.fragment && current_function != varying_function_names.light) {
+ error = true;
+ }
+ } else if (current_function != varying_function_names.fragment) { // inout/out
+ error = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (error) {
+ _set_error(vformat("Varying '%s' cannot be passed for the '%s' parameter in that context!", varname, _get_qualifier_str(arg_qual)));
+ return nullptr;
+ }
+ }
+ }
+
+ bool is_const_arg = call_function->arguments[i].is_const;
+
+ if (is_const_arg || is_out_arg) {
+ StringName varname;
+
+ if (n->type == Node::TYPE_CONSTANT || n->type == Node::TYPE_OPERATOR || n->type == Node::TYPE_ARRAY_CONSTRUCT) {
+ if (!is_const_arg) {
error = true;
}
} else if (n->type == Node::TYPE_ARRAY) {
ArrayNode *an = static_cast<ArrayNode *>(n);
- if (an->call_expression != nullptr || an->is_const) {
+ if (!is_const_arg && (an->call_expression != nullptr || an->is_const)) {
error = true;
}
+ varname = an->name;
} else if (n->type == Node::TYPE_VARIABLE) {
VariableNode *vn = static_cast<VariableNode *>(n);
- if (vn->is_const) {
+ if (vn->is_const && !is_const_arg) {
error = true;
- } else {
- StringName varname = vn->name;
- if (shader->constants.has(varname)) {
- error = true;
- } else if (shader->uniforms.has(varname)) {
- error = true;
- } else {
- if (shader->varyings.has(varname)) {
- _set_error(vformat("Varyings cannot be passed for '%s' parameter!", _get_qualifier_str(call_function->arguments[i].qualifier)));
- return nullptr;
- }
- if (p_function_info.built_ins.has(varname)) {
- BuiltInInfo info = p_function_info.built_ins[varname];
- if (info.constant) {
- error = true;
- }
- }
- }
}
+ varname = vn->name;
} else if (n->type == Node::TYPE_MEMBER) {
MemberNode *mn = static_cast<MemberNode *>(n);
- if (mn->basetype_const) {
+ if (mn->basetype_const && is_out_arg) {
+ error = true;
+ }
+ }
+ if (!error && varname != StringName()) {
+ if (shader->constants.has(varname)) {
+ error = true;
+ } else if (shader->uniforms.has(varname)) {
error = true;
+ } else if (p_function_info.built_ins.has(varname)) {
+ BuiltInInfo info = p_function_info.built_ins[varname];
+ if (info.constant) {
+ error = true;
+ }
}
}
+
if (error) {
- _set_error(vformat("Constant value cannot be passed for '%s' parameter!", _get_qualifier_str(call_function->arguments[i].qualifier)));
+ _set_error(vformat("Constant value cannot be passed for '%s' parameter!", _get_qualifier_str(arg_qual)));
return nullptr;
}
}
if (is_sampler_type(call_function->arguments[i].type)) {
//let's see where our argument comes from
- Node *n = func->arguments[argidx];
ERR_CONTINUE(n->type != Node::TYPE_VARIABLE); //bug? this should always be a variable
VariableNode *vn = static_cast<VariableNode *>(n);
StringName varname = vn->name;
@@ -5068,9 +5175,21 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
} else {
- if (!_validate_varying_using(shader->varyings[identifier], &error)) {
- _set_error(error);
- return nullptr;
+ ShaderNode::Varying &var = shader->varyings[identifier];
+
+ switch (var.stage) {
+ case ShaderNode::Varying::STAGE_VERTEX:
+ if (current_function == varying_function_names.fragment || current_function == varying_function_names.light) {
+ var.stage = ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT_LIGHT;
+ }
+ break;
+ case ShaderNode::Varying::STAGE_FRAGMENT:
+ if (current_function == varying_function_names.light) {
+ var.stage = ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT;
+ }
+ break;
+ default:
+ break;
}
}
}
@@ -5208,9 +5327,21 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.push_back(e);
continue;
} else {
- _set_error("Expected expression, found: " + get_token_text(tk));
- return nullptr;
- //nothing
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected expression, found: " + get_token_text(tk));
+ return nullptr;
+ } else {
+#ifdef DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
+ _add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning.");
+ }
+#endif // DEBUG_ENABLED
+ _set_tkpos(prepos);
+
+ OperatorNode *func = alloc_node<OperatorNode>();
+ func->op = OP_EMPTY;
+ expr = func;
+ }
}
ERR_FAIL_COND_V(!expr, nullptr);
@@ -5223,7 +5354,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_CURSOR) {
//do nothing
- } else if (tk.type == TK_IDENTIFIER) {
} else if (tk.type == TK_PERIOD) {
DataType dt = expr->get_datatype();
String st = expr->get_datatype_name();
@@ -6012,7 +6142,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
ERR_FAIL_V(nullptr); //unexpected operator
}
-#if DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
if (check_warnings && HAS_WARNING(ShaderWarning::FLOAT_COMPARISON_FLAG) && (op == OP_EQUAL || op == OP_NOT_EQUAL) &&
(!expression[i - 1].is_op && !expression[i + 1].is_op) &&
(expression[i - 1].node->get_datatype() == TYPE_FLOAT && expression[i + 1].node->get_datatype() == TYPE_FLOAT)) {
@@ -6329,6 +6459,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
String struct_name = "";
if (is_struct) {
struct_name = tk.text;
+#ifdef DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(struct_name)) {
+ used_structs[struct_name].used = true;
+ }
+#endif // DEBUG_ENABLED
}
bool is_const = false;
@@ -6374,49 +6509,44 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR;
}
- tk = _get_token();
-
Node *vardecl = nullptr;
+ int array_size = 0;
+ bool fixed_array_size = false;
+ bool first = true;
- while (true) {
+ do {
bool unknown_size = false;
- int array_size = 0;
+ Node *size_expr = nullptr;
ArrayDeclarationNode *anode = nullptr;
ArrayDeclarationNode::Declaration adecl;
- if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '[' after type.");
- return ERR_PARSE_ERROR;
- }
+ tk = _get_token();
- if (tk.type == TK_BRACKET_OPEN) {
- anode = alloc_node<ArrayDeclarationNode>();
+ if (first) {
+ first = false;
- if (is_struct) {
- anode->struct_name = struct_name;
- anode->datatype = TYPE_STRUCT;
- } else {
- anode->datatype = type;
+ if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
+ _set_error("Expected identifier or '[' after datatype.");
+ return ERR_PARSE_ERROR;
}
- anode->precision = precision;
- anode->is_const = is_const;
- vardecl = (Node *)anode;
-
- adecl.size = 0U;
- adecl.single_expression = false;
+ if (tk.type == TK_BRACKET_OPEN) {
+ Error error = _parse_local_array_size(p_block, p_function_info, size_expr, array_size, unknown_size);
+ if (error != OK) {
+ return error;
+ }
+ adecl.single_expression = false;
+ adecl.size = array_size;
- Error error = _parse_local_array_size(p_block, p_function_info, anode, &adecl, array_size, unknown_size);
- if (error != OK) {
- return error;
+ fixed_array_size = true;
+ tk = _get_token();
}
- tk = _get_token();
+ }
- if (tk.type != TK_IDENTIFIER) {
- _set_error("Expected identifier!");
- return ERR_PARSE_ERROR;
- }
+ if (tk.type != TK_IDENTIFIER) {
+ _set_error("Expected identifier!");
+ return ERR_PARSE_ERROR;
}
StringName name = tk.text;
@@ -6454,8 +6584,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
+ bool is_array_decl = var.array_size > 0 || unknown_size;
+
if (tk.type == TK_BRACKET_OPEN) {
- if (var.array_size > 0 || unknown_size) {
+ if (is_array_decl) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
@@ -6465,28 +6597,37 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return ERR_PARSE_ERROR;
}
- anode = alloc_node<ArrayDeclarationNode>();
- if (is_struct) {
- anode->struct_name = struct_name;
- anode->datatype = TYPE_STRUCT;
- } else {
- anode->datatype = type;
+ Error error = _parse_local_array_size(p_block, p_function_info, size_expr, var.array_size, unknown_size);
+ if (error != OK) {
+ return error;
}
- anode->precision = precision;
- anode->is_const = is_const;
- vardecl = (Node *)anode;
- adecl.size = 0U;
adecl.single_expression = false;
+ adecl.size = var.array_size;
+ array_size = var.array_size;
- Error error = _parse_local_array_size(p_block, p_function_info, anode, &adecl, var.array_size, unknown_size);
- if (error != OK) {
- return error;
- }
+ is_array_decl = true;
tk = _get_token();
}
- if (var.array_size > 0 || unknown_size) {
+ if (is_array_decl) {
+ {
+ anode = alloc_node<ArrayDeclarationNode>();
+
+ if (is_struct) {
+ anode->struct_name = struct_name;
+ anode->datatype = TYPE_STRUCT;
+ } else {
+ anode->datatype = type;
+ }
+
+ anode->precision = precision;
+ anode->is_const = is_const;
+ anode->size_expression = size_expr;
+
+ vardecl = (Node *)anode;
+ }
+
bool full_def = false;
if (tk.type == TK_OP_ASSIGN) {
@@ -6704,6 +6845,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
}
+ array_size = var.array_size;
anode->declarations.push_back(adecl);
} else if (tk.type == TK_OP_ASSIGN) {
VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>();
@@ -6772,22 +6914,24 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
p_block->statements.push_back(vardecl);
-
p_block->variables[name] = var;
+
+ if (!fixed_array_size) {
+ array_size = 0;
+ }
+
if (tk.type == TK_COMMA) {
if (p_block->block_type == BlockNode::BLOCK_TYPE_FOR) {
_set_error("Multiple declarations in 'for' loop are not implemented yet.");
return ERR_PARSE_ERROR;
}
- tk = _get_token();
- //another variable
} else if (tk.type == TK_SEMICOLON) {
break;
} else {
_set_error("Expected ',' or ';' after variable");
return ERR_PARSE_ERROR;
}
- }
+ } while (tk.type == TK_COMMA); //another variable
} else if (tk.type == TK_CURLY_BRACKET_OPEN) {
//a sub block, just because..
BlockNode *block = alloc_node<BlockNode>();
@@ -6840,7 +6984,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
block->parent_block = p_block;
cf->blocks.push_back(block);
err = _parse_block(block, p_function_info, true, p_can_break, p_can_continue);
-
+ if (err) {
+ return err;
+ }
} else {
_set_tkpos(pos); //rollback
}
@@ -6970,7 +7116,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
Node *n = nullptr;
- if (tk.type != TK_INT_CONSTANT) {
+ if (!tk.is_integer_constant()) {
bool correct_constant_expression = false;
DataType data_type;
@@ -6993,11 +7139,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
n = vn;
} else {
ConstantNode::Value v;
- v.sint = (int)tk.constant * sign;
+ if (tk.type == TK_UINT_CONSTANT) {
+ v.uint = (uint32_t)tk.constant;
+ } else {
+ v.sint = (int)tk.constant * sign;
+ }
ConstantNode *cn = alloc_node<ConstantNode>();
cn->values.push_back(v);
- cn->datatype = TYPE_INT;
+ cn->datatype = (tk.type == TK_UINT_CONSTANT ? TYPE_UINT : TYPE_INT);
n = cn;
}
@@ -7219,7 +7369,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
if (tk.type == TK_SEMICOLON) {
//all is good
if (b->parent_function->return_type != TYPE_VOID) {
- _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
+ _set_error("Expected return with an expression of type '" + (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
return ERR_PARSE_ERROR;
}
} else {
@@ -7231,7 +7381,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (b->parent_function->return_type != expr->get_datatype() || b->parent_function->return_array_size != expr->get_array_size() || return_struct_name != expr->get_datatype_name()) {
- _set_error("Expected return with an expression of type '" + (return_struct_name != "" ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
+ _set_error("Expected return with an expression of type '" + (!return_struct_name.is_empty() ? return_struct_name : get_datatype_name(b->parent_function->return_type)) + array_size_string + "'");
return ERR_PARSE_ERROR;
}
@@ -7353,7 +7503,7 @@ String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types)
// Return a list of shader types as an human-readable string
String valid_types;
for (const Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) {
- if (valid_types != String()) {
+ if (!valid_types.is_empty()) {
valid_types += ", ";
}
@@ -7404,7 +7554,7 @@ Error ShaderLanguage::_validate_datatype(DataType p_type) {
return OK;
}
-Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) {
+Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const Set<String> &p_shader_types) {
Token tk = _get_token();
TkPos prev_pos;
@@ -7443,9 +7593,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int texture_binding = 0;
int uniforms = 0;
int instance_index = 0;
+#ifdef DEBUG_ENABLED
+ int uniform_buffer_size = 0;
+ int max_uniform_buffer_size = 0;
+ if (RenderingDevice::get_singleton()) {
+ max_uniform_buffer_size = RenderingDevice::get_singleton()->limit_get(RenderingDevice::LIMIT_MAX_UNIFORM_BUFFER_SIZE);
+ }
+#endif // DEBUG_ENABLED
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
stages = &p_functions;
+ const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo();
+
+ Map<String, String> defined_modes;
while (tk.type != TK_EOF) {
switch (tk.type) {
@@ -7459,13 +7619,40 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- if (p_render_modes.find(mode) == -1) {
- _set_error("Invalid render mode: '" + String(mode) + "'");
+ const String smode = String(mode);
+
+ if (shader->render_modes.find(mode) != -1) {
+ _set_error(vformat("Duplicated render mode: '%s'.", smode));
return ERR_PARSE_ERROR;
}
- if (shader->render_modes.find(mode) != -1) {
- _set_error("Duplicate render mode: '" + String(mode) + "'");
+ bool found = false;
+
+ for (int i = 0; i < p_render_modes.size(); i++) {
+ const ModeInfo &info = p_render_modes[i];
+ const String name = String(info.name);
+
+ if (smode.begins_with(name)) {
+ if (!info.options.is_empty()) {
+ if (info.options.find(smode.substr(name.length() + 1)) != -1) {
+ found = true;
+
+ if (defined_modes.has(name)) {
+ _set_error(vformat("Redefinition of render mode: '%s'. The %s mode has already been set to '%s'.", smode, name, defined_modes[name]));
+ return ERR_PARSE_ERROR;
+ }
+ defined_modes.insert(name, smode);
+ break;
+ }
+ } else {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ _set_error(vformat("Invalid render mode: '%s'.", smode));
return ERR_PARSE_ERROR;
}
@@ -7489,7 +7676,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_IDENTIFIER) {
st.name = tk.text;
- if (shader->structs.has(st.name)) {
+ if (shader->constants.has(st.name) || shader->structs.has(st.name)) {
_set_error("Redefinition of '" + String(st.name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7531,6 +7718,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (shader->structs.has(tk.text)) {
struct_name = tk.text;
+#ifdef DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(struct_name)) {
+ used_structs[struct_name].used = true;
+ }
+#endif // DEBUG_ENABLED
struct_dt = true;
if (use_precision) {
_set_error("Precision modifier cannot be used on structs.");
@@ -7551,57 +7743,71 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_set_error("void datatype not allowed here");
return ERR_PARSE_ERROR;
}
- tk = _get_token();
-
- if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '['.");
- return ERR_PARSE_ERROR;
- }
+ bool first = true;
+ bool fixed_array_size = false;
int array_size = 0;
- if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
- if (error != OK) {
- return error;
- }
+ do {
tk = _get_token();
- }
- if (tk.type != TK_IDENTIFIER) {
- _set_error("Expected identifier!");
- return ERR_PARSE_ERROR;
- }
+ if (first) {
+ first = false;
- MemberNode *member = alloc_node<MemberNode>();
- member->precision = precision;
- member->datatype = type;
- member->struct_name = struct_name;
- member->name = tk.text;
- member->array_size = array_size;
+ if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
+ _set_error("Expected identifier or '['.");
+ return ERR_PARSE_ERROR;
+ }
- if (member_names.has(member->name)) {
- _set_error("Redefinition of '" + String(member->name) + "'");
- return ERR_PARSE_ERROR;
- }
- member_names.insert(member->name);
- tk = _get_token();
+ if (tk.type == TK_BRACKET_OPEN) {
+ Error error = _parse_global_array_size(array_size, constants);
+ if (error != OK) {
+ return error;
+ }
+ fixed_array_size = true;
+ tk = _get_token();
+ }
+ }
- if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(member->array_size);
- if (error != OK) {
- return error;
+ if (tk.type != TK_IDENTIFIER) {
+ _set_error("Expected identifier!");
+ return ERR_PARSE_ERROR;
}
+
+ MemberNode *member = alloc_node<MemberNode>();
+ member->precision = precision;
+ member->datatype = type;
+ member->struct_name = struct_name;
+ member->name = tk.text;
+ member->array_size = array_size;
+
+ if (member_names.has(member->name)) {
+ _set_error("Redefinition of '" + String(member->name) + "'");
+ return ERR_PARSE_ERROR;
+ }
+ member_names.insert(member->name);
tk = _get_token();
- }
- if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
- return ERR_PARSE_ERROR;
- }
+ if (tk.type == TK_BRACKET_OPEN) {
+ Error error = _parse_global_array_size(member->array_size, constants);
+ if (error != OK) {
+ return error;
+ }
+ tk = _get_token();
+ }
+
+ if (!fixed_array_size) {
+ array_size = 0;
+ }
- st_node->members.push_back(member);
- member_count++;
+ if (tk.type != TK_SEMICOLON && tk.type != TK_COMMA) {
+ _set_error("Expected ',' or ';' after struct member.");
+ return ERR_PARSE_ERROR;
+ }
+
+ st_node->members.push_back(member);
+ member_count++;
+ } while (tk.type == TK_COMMA); // another member
}
}
if (member_count == 0) {
@@ -7715,7 +7921,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
+ Error error = _parse_global_array_size(array_size, constants);
if (error != OK) {
return error;
}
@@ -7730,7 +7936,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7763,7 +7969,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(uniform2.array_size);
+ Error error = _parse_global_array_size(uniform2.array_size, constants);
if (error != OK) {
return error;
}
@@ -7794,6 +8000,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform2.texture_order = -1;
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
uniform2.order = uniforms++;
+#ifdef DEBUG_ENABLED
+ if (uniform2.array_size > 0) {
+ int size = get_datatype_size(uniform2.type) * uniform2.array_size;
+ int m = (16 * uniform2.array_size);
+ if ((size % m) != 0U) {
+ size += m - (size % m);
+ }
+ uniform_buffer_size += size;
+ } else {
+ uniform_buffer_size += get_datatype_size(uniform2.type);
+ }
+#endif // DEBUG_ENABLED
}
}
@@ -7811,9 +8029,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int custom_instance_index = -1;
if (tk.type == TK_COLON) {
+ completion_type = COMPLETION_HINT;
+ completion_base = type;
+ completion_base_array = uniform2.array_size > 0;
+
//hint
do {
tk = _get_token();
+ completion_line = tk.line;
+
+ if (!is_token_hint(tk.type)) {
+ _set_error("Expected valid type hint after ':'.");
+ return ERR_PARSE_ERROR;
+ }
if (uniform2.array_size > 0) {
if (tk.type != TK_HINT_COLOR) {
@@ -7840,8 +8068,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_A;
} else if (tk.type == TK_HINT_ROUGHNESS_GRAY) {
uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_GRAY;
- } else if (tk.type == TK_HINT_ANISO_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_ANISO;
+ } else if (tk.type == TK_HINT_ANISOTROPY_TEXTURE) {
+ uniform2.hint = ShaderNode::Uniform::HINT_ANISOTROPY;
} else if (tk.type == TK_HINT_ALBEDO_TEXTURE) {
uniform2.hint = ShaderNode::Uniform::HINT_ALBEDO;
} else if (tk.type == TK_HINT_BLACK_ALBEDO_TEXTURE) {
@@ -7874,7 +8102,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) {
+ if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
_set_error("Expected integer constant");
return ERR_PARSE_ERROR;
}
@@ -7898,7 +8126,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) {
+ if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
_set_error("Expected integer constant after ','");
return ERR_PARSE_ERROR;
}
@@ -7911,7 +8139,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_COMMA) {
tk = _get_token();
- if (tk.type != TK_FLOAT_CONSTANT && tk.type != TK_INT_CONSTANT) {
+ if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
_set_error("Expected integer constant after ','");
return ERR_PARSE_ERROR;
}
@@ -7949,7 +8177,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- if (tk.type != TK_INT_CONSTANT) {
+ if (!tk.is_integer_constant()) {
_set_error("Expected integer constant");
return ERR_PARSE_ERROR;
}
@@ -7975,16 +8203,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
uniform2.filter = FILTER_NEAREST_MIPMAP;
} else if (tk.type == TK_FILTER_LINEAR_MIPMAP) {
uniform2.filter = FILTER_LINEAR_MIPMAP;
- } else if (tk.type == TK_FILTER_NEAREST_MIPMAP_ANISO) {
- uniform2.filter = FILTER_NEAREST_MIPMAP_ANISO;
- } else if (tk.type == TK_FILTER_LINEAR_MIPMAP_ANISO) {
- uniform2.filter = FILTER_LINEAR_MIPMAP_ANISO;
+ } else if (tk.type == TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC) {
+ uniform2.filter = FILTER_NEAREST_MIPMAP_ANISOTROPIC;
+ } else if (tk.type == TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC) {
+ uniform2.filter = FILTER_LINEAR_MIPMAP_ANISOTROPIC;
} else if (tk.type == TK_REPEAT_DISABLE) {
uniform2.repeat = REPEAT_DISABLE;
} else if (tk.type == TK_REPEAT_ENABLE) {
uniform2.repeat = REPEAT_ENABLE;
- } else {
- _set_error("Expected valid type hint after ':'.");
}
if (uniform2.hint != ShaderNode::Uniform::HINT_RANGE && uniform2.hint != ShaderNode::Uniform::HINT_NONE && uniform2.hint != ShaderNode::Uniform::HINT_COLOR && type <= TYPE_MAT4) {
@@ -8017,7 +8243,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8051,6 +8277,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_set_error("Expected ';'");
return ERR_PARSE_ERROR;
}
+
+ completion_type = COMPLETION_NONE;
} else { // varying
ShaderNode::Varying varying;
varying.type = type;
@@ -8075,7 +8303,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
tk = _get_token();
- if (tk.type == TK_INT_CONSTANT && tk.constant > 0) {
+ if (tk.is_integer_constant() && tk.constant > 0) {
varying.array_size = (int)tk.constant;
tk = _get_token();
@@ -8113,7 +8341,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
DataPrecision precision = PRECISION_DEFAULT;
DataType type;
StringName name;
- int return_array_size = 0;
+ int array_size = 0;
if (tk.type == TK_CONST) {
is_constant = true;
@@ -8152,13 +8380,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
tk = _get_token();
+ bool unknown_size = false;
+
if (tk.type == TK_BRACKET_OPEN) {
+ if (is_constant && RenderingServer::get_singleton()->is_low_end()) {
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
bool error = false;
tk = _get_token();
- if (tk.type == TK_INT_CONSTANT) {
- return_array_size = (int)tk.constant;
- if (return_array_size > 0) {
+ if (tk.is_integer_constant()) {
+ array_size = (int)tk.constant;
+ if (array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8167,11 +8401,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
error = true;
}
+ } else if (tk.type == TK_BRACKET_CLOSE) {
+ unknown_size = true;
} else {
error = true;
}
if (error) {
- _set_error("Expected integer constant > 0");
+ _set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
}
@@ -8183,16 +8419,15 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name);
if (name == StringName()) {
- _set_error("Expected function name after datatype");
- return ERR_PARSE_ERROR;
- }
-
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ if (is_constant) {
+ _set_error("Expected identifier or '[' after datatype.");
+ } else {
+ _set_error("Expected function name after datatype.");
+ }
return ERR_PARSE_ERROR;
}
- if (has_builtin(p_functions, name)) {
+ if (shader->structs.has(name) || _find_identifier(nullptr, false, constants, name) || has_builtin(p_functions, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8205,7 +8440,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
//variable
-
+ bool first = true;
while (true) {
ShaderNode::Constant constant;
constant.name = name;
@@ -8213,21 +8448,23 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.type_str = struct_name;
constant.precision = precision;
constant.initializer = nullptr;
- constant.array_size = 0;
-
- bool unknown_size = false;
+ constant.array_size = (first ? array_size : 0);
+ first = false;
if (tk.type == TK_BRACKET_OPEN) {
if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error("Global const arrays are supported only on high-end platform!");
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
+ if (constant.array_size > 0 || unknown_size) {
+ _set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
-
tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
unknown_size = true;
tk = _get_token();
- } else if (tk.type == TK_INT_CONSTANT && ((int)tk.constant) > 0) {
+ } else if (tk.is_integer_constant() && ((int)tk.constant) > 0) {
constant.array_size = (int)tk.constant;
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
@@ -8300,7 +8537,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
_set_tkpos(prev_pos);
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -8381,7 +8618,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -8436,7 +8673,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
} else {
//variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8452,7 +8689,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
- if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), 0)) {
+ if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), expr->get_array_size())) {
return ERR_PARSE_ERROR;
}
}
@@ -8483,7 +8720,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8517,6 +8754,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
}
+ if (p_functions.has("constants")) { // Adds global constants: 'PI', 'TAU', 'E'
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
+ builtins.built_ins.insert(E.key, E.value);
+ }
+ }
+
ShaderNode::Function function;
function.callable = !p_functions.has(name);
@@ -8532,7 +8775,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
func_node->return_type = type;
func_node->return_struct_name = struct_name;
func_node->return_precision = precision;
- func_node->return_array_size = return_array_size;
+ func_node->return_array_size = array_size;
if (p_functions.has(name)) {
func_node->can_discard = p_functions[name].can_discard;
@@ -8586,7 +8829,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
StringName param_struct_name;
DataPrecision pprecision = PRECISION_DEFAULT;
bool use_precision = false;
- int array_size = 0;
+ int arg_array_size = 0;
if (is_token_precision(tk.type)) {
pprecision = get_token_precision(tk.type);
@@ -8599,6 +8842,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (shader->structs.has(tk.text)) {
is_struct = true;
param_struct_name = tk.text;
+#ifdef DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_STRUCT_FLAG) && used_structs.has(param_struct_name)) {
+ used_structs[param_struct_name].used = true;
+ }
+#endif // DEBUG_ENABLED
if (use_precision) {
_set_error("Precision modifier cannot be used on structs.");
return ERR_PARSE_ERROR;
@@ -8636,10 +8884,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
bool error = false;
tk = _get_token();
- if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ if (tk.is_integer_constant()) {
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8691,17 +8939,17 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- if (array_size > 0) {
+ if (arg_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
bool error = false;
tk = _get_token();
- if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ if (tk.is_integer_constant()) {
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8721,7 +8969,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- arg.array_size = array_size;
+ arg.array_size = arg_array_size;
func_node->arguments.push_back(arg);
if (tk.type == TK_COMMA) {
@@ -8773,14 +9021,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- int error_line;
- String error_message;
- if (!_check_varying_usages(&error_line, &error_message)) {
- _set_tkpos({ 0, error_line });
- _set_error(error_message);
- return ERR_PARSE_ERROR;
+#ifdef DEBUG_ENABLED
+ if (HAS_WARNING(ShaderWarning::DEVICE_LIMIT_EXCEEDED) && (uniform_buffer_size > max_uniform_buffer_size)) {
+ Vector<Variant> args;
+ args.push_back(uniform_buffer_size);
+ args.push_back(max_uniform_buffer_size);
+ _add_global_warning(ShaderWarning::DEVICE_LIMIT_EXCEEDED, "uniform buffer", args);
}
-
+#endif // DEBUG_ENABLED
return OK;
}
@@ -8900,7 +9148,7 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
break;
} else if (p_code[i] <= 32) {
- if (cur_identifier != String()) {
+ if (!cur_identifier.is_empty()) {
if (!reading_type) {
if (cur_identifier != "shader_type") {
return String();
@@ -8960,17 +9208,17 @@ uint32_t ShaderLanguage::get_warning_flags() const {
}
#endif // DEBUG_ENABLED
-Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) {
+Error ShaderLanguage::compile(const String &p_code, const ShaderCompileInfo &p_info) {
clear();
code = p_code;
- global_var_get_type_func = p_global_variable_type_func;
- varying_function_names = p_varying_function_names;
+ global_var_get_type_func = p_info.global_variable_type_func;
+ varying_function_names = p_info.varying_function_names;
nodes = nullptr;
shader = alloc_node<ShaderNode>();
- Error err = _parse_shader(p_functions, p_render_modes, p_shader_types);
+ Error err = _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types);
#ifdef DEBUG_ENABLED
if (check_warnings) {
@@ -8984,17 +9232,17 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi
return OK;
}
-Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) {
+Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) {
clear();
code = p_code;
- varying_function_names = p_varying_function_names;
+ varying_function_names = p_info.varying_function_names;
nodes = nullptr;
- global_var_get_type_func = p_global_variable_type_func;
+ global_var_get_type_func = p_info.global_variable_type_func;
shader = alloc_node<ShaderNode>();
- _parse_shader(p_functions, p_render_modes, p_shader_types);
+ _parse_shader(p_info.functions, p_info.render_modes, p_info.shader_types);
switch (completion_type) {
case COMPLETION_NONE: {
@@ -9002,9 +9250,32 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
return OK;
} break;
case COMPLETION_RENDER_MODE: {
- for (int i = 0; i < p_render_modes.size(); i++) {
- ScriptCodeCompletionOption option(p_render_modes[i], ScriptCodeCompletionOption::KIND_ENUM);
- r_options->push_back(option);
+ for (int i = 0; i < p_info.render_modes.size(); i++) {
+ const ModeInfo &info = p_info.render_modes[i];
+
+ if (!info.options.is_empty()) {
+ bool found = false;
+
+ for (int j = 0; j < info.options.size(); j++) {
+ if (shader->render_modes.has(String(info.name) + "_" + String(info.options[j]))) {
+ found = true;
+ }
+ }
+
+ if (!found) {
+ for (int j = 0; j < info.options.size(); j++) {
+ ScriptCodeCompletionOption option(String(info.name) + "_" + String(info.options[j]), ScriptCodeCompletionOption::KIND_ENUM);
+ r_options->push_back(option);
+ }
+ }
+ } else {
+ const String name = String(info.name);
+
+ if (!shader->render_modes.has(name)) {
+ ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_ENUM);
+ r_options->push_back(option);
+ }
+ }
}
return OK;
@@ -9021,7 +9292,7 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
return OK;
} break;
case COMPLETION_MAIN_FUNCTION: {
- for (const KeyValue<StringName, FunctionInfo> &E : p_functions) {
+ for (const KeyValue<StringName, FunctionInfo> &E : p_info.functions) {
ScriptCodeCompletionOption option(E.key, ScriptCodeCompletionOption::KIND_FUNCTION);
r_options->push_back(option);
}
@@ -9057,8 +9328,18 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (comp_ident) {
- if (p_functions.has("global")) {
- for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["global"].built_ins) {
+ if (p_info.functions.has("global")) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["global"].built_ins) {
+ ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
+ if (E.value.constant) {
+ kind = ScriptCodeCompletionOption::KIND_CONSTANT;
+ }
+ matches.insert(E.key, kind);
+ }
+ }
+
+ if (p_info.functions.has("constants")) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions["constants"].built_ins) {
ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
if (E.value.constant) {
kind = ScriptCodeCompletionOption::KIND_CONSTANT;
@@ -9067,8 +9348,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
}
- if (skip_function != StringName() && p_functions.has(skip_function)) {
- for (const KeyValue<StringName, BuiltInInfo> &E : p_functions[skip_function].built_ins) {
+ if (skip_function != StringName() && p_info.functions.has(skip_function)) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_info.functions[skip_function].built_ins) {
ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
if (E.value.constant) {
kind = ScriptCodeCompletionOption::KIND_CONSTANT;
@@ -9383,6 +9664,57 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
} break;
+ case COMPLETION_HINT: {
+ if (completion_base == DataType::TYPE_VEC4) {
+ ScriptCodeCompletionOption option("hint_color", ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+ r_options->push_back(option);
+ } else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) {
+ ScriptCodeCompletionOption option("hint_range", ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+
+ if (completion_base == DataType::TYPE_INT) {
+ option.insert_text = "hint_range(0, 100, 1)";
+ } else {
+ option.insert_text = "hint_range(0.0, 1.0, 0.1)";
+ }
+
+ r_options->push_back(option);
+ } else if ((int(completion_base) > int(TYPE_MAT4) && int(completion_base) < int(TYPE_STRUCT)) && !completion_base_array) {
+ static Vector<String> options;
+
+ if (options.is_empty()) {
+ options.push_back("filter_linear");
+ options.push_back("filter_linear_mipmap");
+ options.push_back("filter_linear_mipmap_anisotropic");
+ options.push_back("filter_nearest");
+ options.push_back("filter_nearest_mipmap");
+ options.push_back("filter_nearest_mipmap_anisotropic");
+ options.push_back("hint_albedo");
+ options.push_back("hint_anisotropy");
+ options.push_back("hint_black");
+ options.push_back("hint_black_albedo");
+ options.push_back("hint_normal");
+ options.push_back("hint_roughness_a");
+ options.push_back("hint_roughness_b");
+ options.push_back("hint_roughness_g");
+ options.push_back("hint_roughness_gray");
+ options.push_back("hint_roughness_normal");
+ options.push_back("hint_roughness_r");
+ options.push_back("hint_white");
+ options.push_back("repeat_enable");
+ options.push_back("repeat_disable");
+ }
+
+ for (int i = 0; i < options.size(); i++) {
+ ScriptCodeCompletionOption option(options[i], ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+ r_options->push_back(option);
+ }
+ }
+ if (!completion_base_array) {
+ ScriptCodeCompletionOption option("instance_index", ScriptCodeCompletionOption::KIND_PLAIN_TEXT);
+ option.insert_text = "instance_index(0)";
+ r_options->push_back(option);
+ }
+ } break;
}
return ERR_PARSE_ERROR;
@@ -9404,7 +9736,7 @@ ShaderLanguage::ShaderLanguage() {
nodes = nullptr;
completion_class = TAG_GLOBAL;
-#if DEBUG_ENABLED
+#ifdef DEBUG_ENABLED
warnings_check_map.insert(ShaderWarning::UNUSED_CONSTANT, &used_constants);
warnings_check_map.insert(ShaderWarning::UNUSED_FUNCTION, &used_functions);
warnings_check_map.insert(ShaderWarning::UNUSED_STRUCT, &used_structs);
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index c82f71d10d..b9c2d4b33c 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -57,6 +57,7 @@ public:
TK_FALSE,
TK_FLOAT_CONSTANT,
TK_INT_CONSTANT,
+ TK_UINT_CONSTANT,
TK_TYPE_VOID,
TK_TYPE_BOOL,
TK_TYPE_BVEC2,
@@ -168,7 +169,7 @@ public:
TK_HINT_ROUGHNESS_B,
TK_HINT_ROUGHNESS_A,
TK_HINT_ROUGHNESS_GRAY,
- TK_HINT_ANISO_TEXTURE,
+ TK_HINT_ANISOTROPY_TEXTURE,
TK_HINT_ALBEDO_TEXTURE,
TK_HINT_BLACK_ALBEDO_TEXTURE,
TK_HINT_COLOR,
@@ -178,8 +179,8 @@ public:
TK_FILTER_LINEAR,
TK_FILTER_NEAREST_MIPMAP,
TK_FILTER_LINEAR_MIPMAP,
- TK_FILTER_NEAREST_MIPMAP_ANISO,
- TK_FILTER_LINEAR_MIPMAP_ANISO,
+ TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC,
+ TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC,
TK_REPEAT_ENABLE,
TK_REPEAT_DISABLE,
TK_SHADER_TYPE,
@@ -287,6 +288,7 @@ public:
OP_CONSTRUCT,
OP_STRUCT,
OP_INDEX,
+ OP_EMPTY,
OP_MAX
};
@@ -320,8 +322,8 @@ public:
FILTER_LINEAR,
FILTER_NEAREST_MIPMAP,
FILTER_LINEAR_MIPMAP,
- FILTER_NEAREST_MIPMAP_ANISO,
- FILTER_LINEAR_MIPMAP_ANISO,
+ FILTER_NEAREST_MIPMAP_ANISOTROPIC,
+ FILTER_LINEAR_MIPMAP_ANISOTROPIC,
FILTER_DEFAULT,
};
@@ -574,7 +576,7 @@ public:
virtual DataType get_datatype() const override { return datatype; }
virtual String get_datatype_name() const override { return String(struct_name); }
- virtual int get_array_size() const override { return array_size; }
+ virtual int get_array_size() const override { return (index_expression || call_expression) ? 0 : array_size; }
virtual bool is_indexed() const override { return index_expression != nullptr || call_expression != nullptr; }
MemberNode() :
@@ -680,7 +682,7 @@ public:
HINT_ROUGHNESS_GRAY,
HINT_BLACK,
HINT_WHITE,
- HINT_ANISO,
+ HINT_ANISOTROPY,
HINT_MAX
};
@@ -747,6 +749,7 @@ public:
COMPLETION_CALL_ARGUMENTS,
COMPLETION_INDEX,
COMPLETION_STRUCT,
+ COMPLETION_HINT,
};
struct Token {
@@ -754,6 +757,9 @@ public:
StringName text;
double constant;
uint16_t line;
+ bool is_integer_constant() const {
+ return type == TK_INT_CONSTANT || type == TK_UINT_CONSTANT;
+ }
};
static String get_operator_text(Operator p_op);
@@ -771,6 +777,7 @@ public:
static bool is_token_nonvoid_datatype(TokenType p_type);
static bool is_token_operator(TokenType p_type);
static bool is_token_operator_assign(TokenType p_type);
+ static bool is_token_hint(TokenType p_type);
static bool convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value = nullptr);
static DataType get_scalar_type(DataType p_type);
@@ -780,7 +787,7 @@ public:
static bool is_sampler_type(DataType p_type);
static Variant constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE);
static PropertyInfo uniform_to_property_info(const ShaderNode::Uniform &p_uniform);
- static uint32_t get_type_size(DataType p_type);
+ static uint32_t get_datatype_size(DataType p_type);
static void get_keyword_list(List<String> *r_keywords);
static bool is_control_flow_keyword(String p_keyword);
@@ -812,6 +819,57 @@ public:
DataType return_type = TYPE_VOID;
};
+ struct ModeInfo {
+ StringName name;
+ Vector<StringName> options;
+
+ ModeInfo() {}
+
+ ModeInfo(const StringName &p_name) :
+ name(p_name) {
+ }
+
+ ModeInfo(const StringName &p_name, const StringName &p_arg1, const StringName &p_arg2) :
+ name(p_name) {
+ options.push_back(p_arg1);
+ options.push_back(p_arg2);
+ }
+
+ ModeInfo(const StringName &p_name, const StringName &p_arg1, const StringName &p_arg2, const StringName &p_arg3) :
+ name(p_name) {
+ options.push_back(p_arg1);
+ options.push_back(p_arg2);
+ options.push_back(p_arg3);
+ }
+
+ ModeInfo(const StringName &p_name, const StringName &p_arg1, const StringName &p_arg2, const StringName &p_arg3, const StringName &p_arg4) :
+ name(p_name) {
+ options.push_back(p_arg1);
+ options.push_back(p_arg2);
+ options.push_back(p_arg3);
+ options.push_back(p_arg4);
+ }
+
+ ModeInfo(const StringName &p_name, const StringName &p_arg1, const StringName &p_arg2, const StringName &p_arg3, const StringName &p_arg4, const StringName &p_arg5) :
+ name(p_name) {
+ options.push_back(p_arg1);
+ options.push_back(p_arg2);
+ options.push_back(p_arg3);
+ options.push_back(p_arg4);
+ options.push_back(p_arg5);
+ }
+
+ ModeInfo(const StringName &p_name, const StringName &p_arg1, const StringName &p_arg2, const StringName &p_arg3, const StringName &p_arg4, const StringName &p_arg5, const StringName &p_arg6) :
+ name(p_name) {
+ options.push_back(p_arg1);
+ options.push_back(p_arg2);
+ options.push_back(p_arg3);
+ options.push_back(p_arg4);
+ options.push_back(p_arg5);
+ options.push_back(p_arg6);
+ }
+ };
+
struct FunctionInfo {
Map<StringName, BuiltInInfo> built_ins;
Map<StringName, StageFunctionInfo> stage_functions;
@@ -861,11 +919,14 @@ private:
bool check_warnings = false;
uint32_t warning_flags;
- void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "") {
- warnings.push_back(ShaderWarning(p_code, tk_line, p_subject));
+ void _add_line_warning(ShaderWarning::Code p_code, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()) {
+ warnings.push_back(ShaderWarning(p_code, tk_line, p_subject, p_extra_args));
+ }
+ void _add_global_warning(ShaderWarning::Code p_code, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()) {
+ warnings.push_back(ShaderWarning(p_code, -1, p_subject, p_extra_args));
}
- void _add_warning(ShaderWarning::Code p_code, int p_line, const StringName &p_subject = "") {
- warnings.push_back(ShaderWarning(p_code, p_line, p_subject));
+ void _add_warning(ShaderWarning::Code p_code, int p_line, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()) {
+ warnings.push_back(ShaderWarning(p_code, p_line, p_subject, p_extra_args));
}
void _check_warning_accums();
#endif // DEBUG_ENABLED
@@ -880,14 +941,6 @@ private:
VaryingFunctionNames varying_function_names;
- struct VaryingUsage {
- ShaderNode::Varying *var;
- int line;
- };
- List<VaryingUsage> unknown_varying_usages;
-
- bool _check_varying_usages(int *r_error_line, String *r_error_message) const;
-
TkPos _get_tkpos() {
TkPos tkp;
tkp.char_idx = char_idx;
@@ -965,10 +1018,12 @@ private:
int completion_line;
BlockNode *completion_block;
DataType completion_base;
+ bool completion_base_array;
SubClassTag completion_class;
StringName completion_function;
StringName completion_struct;
int completion_argument;
+
const Map<StringName, FunctionInfo> *stages = nullptr;
bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier);
@@ -976,6 +1031,8 @@ private:
static const BuiltinFuncOutArgs builtin_func_out_args[];
static const BuiltinFuncConstArgs builtin_func_const_args[];
+ static bool is_const_suffix_lut_initialized;
+
Error _validate_datatype(DataType p_type);
bool _compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b);
bool _compare_datatypes_in_nodes(Node *a, Node *b);
@@ -985,12 +1042,11 @@ private:
bool _propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat);
bool _propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin);
bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message);
- bool _validate_varying_using(ShaderNode::Varying &p_varying, String *r_message);
bool _check_node_constness(const Node *p_node) const;
Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size);
- Error _parse_global_array_size(int &r_array_size);
- Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, ArrayDeclarationNode *p_node, ArrayDeclarationNode::Declaration *p_decl, int &r_array_size, bool &r_is_unknown_size);
+ Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info);
+ Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size);
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info);
@@ -1002,7 +1058,7 @@ private:
String _get_shader_type_list(const Set<String> &p_shader_types) const;
String _get_qualifier_str(ArgumentQualifier p_qualifier) const;
- Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types);
+ Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const Set<String> &p_shader_types);
Error _find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op);
Error _find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op);
@@ -1023,8 +1079,17 @@ public:
void clear();
static String get_shader_type(const String &p_code);
- Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func);
- Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const VaryingFunctionNames &p_varying_function_names, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
+
+ struct ShaderCompileInfo {
+ Map<StringName, FunctionInfo> functions;
+ Vector<ModeInfo> render_modes;
+ VaryingFunctionNames varying_function_names = VaryingFunctionNames();
+ Set<String> shader_types;
+ GlobalVariableGetTypeFunc global_variable_type_func = nullptr;
+ };
+
+ Error compile(const String &p_code, const ShaderCompileInfo &p_info);
+ Error complete(const String &p_code, const ShaderCompileInfo &p_info, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint);
String get_error_text();
int get_error_line();
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index eb5c9e66e8..667f8b515f 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -35,7 +35,7 @@ const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(
return shader_modes[p_mode].functions;
}
-const Vector<StringName> &ShaderTypes::get_modes(RS::ShaderMode p_mode) const {
+const Vector<ShaderLanguage::ModeInfo> &ShaderTypes::get_modes(RS::ShaderMode p_mode) const {
return shader_modes[p_mode].modes;
}
@@ -59,9 +59,9 @@ ShaderTypes::ShaderTypes() {
/*************** SPATIAL ***********************/
shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
@@ -190,60 +190,36 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["light"].can_discard = true;
shader_modes[RS::SHADER_SPATIAL].functions["light"].main_function = true;
- //order used puts first enum mode (default) first
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("blend_mix");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("blend_add");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("blend_sub");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("blend_mul");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("depth_draw_opaque");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("depth_draw_always");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("depth_draw_never");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("depth_prepass_alpha");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("depth_test_disabled");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("sss_mode_skin");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("cull_back");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("cull_front");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("cull_disabled");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("unshaded");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("wireframe");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_lambert");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_lambert_wrap");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_burley");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("diffuse_toon");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("specular_schlick_ggx");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("specular_blinn");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("specular_phong");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("specular_toon");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("specular_disabled");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("skip_vertex_transform");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("world_vertex_coords");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("ensure_correct_normals");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("shadows_disabled");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("ambient_light_disabled");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("shadow_to_opacity");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("vertex_lighting");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("particle_trails");
-
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("alpha_to_coverage");
- shader_modes[RS::SHADER_SPATIAL].modes.push_back("alpha_to_coverage_and_one");
+ // spatial render modes
+ {
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "blend", "mix", "add", "sub", "mul" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_draw", "opaque", "always", "never" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_prepass_alpha" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_test_disabled" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "sss_mode_skin" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "cull", "back", "front", "disabled" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "unshaded" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "wireframe" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "diffuse", "lambert", "lambert_wrap", "burley", "toon" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "specular", "schlick_ggx", "blinn", "phong", "toon", "disabled" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "skip_vertex_transform" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "world_vertex_coords" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "ensure_correct_normals" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "shadows_disabled" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "ambient_light_disabled" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "shadow_to_opacity" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "vertex_lighting" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "particle_trails" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "alpha_to_coverage" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "alpha_to_coverage_and_one" });
+ }
/************ CANVAS ITEM **************************/
shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
@@ -319,24 +295,20 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_CANVAS_ITEM].functions["light"].can_discard = true;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["light"].main_function = true;
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("skip_vertex_transform");
-
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("blend_mix");
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("blend_add");
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("blend_sub");
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("blend_mul");
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("blend_premul_alpha");
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("blend_disabled");
-
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("unshaded");
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back("light_only");
+ // canvasitem render modes
+ {
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "skip_vertex_transform" });
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "blend", "mix", "add", "sub", "mul", "premul_alpha", "disabled" });
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "unshaded" });
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "light_only" });
+ }
/************ PARTICLES **************************/
shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
@@ -367,7 +339,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["NUMBER"] = constt(ShaderLanguage::TYPE_UINT);
- shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_INT);
+ shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["INDEX"] = constt(ShaderLanguage::TYPE_UINT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["EMISSION_TRANSFORM"] = constt(ShaderLanguage::TYPE_MAT4);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RANDOM_SEED"] = constt(ShaderLanguage::TYPE_UINT);
shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["FLAG_EMIT_POSITION"] = constt(ShaderLanguage::TYPE_UINT);
@@ -392,17 +364,20 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_PARTICLES].functions["process"].stage_functions["emit_subparticle"] = emit_vertex_func;
}
- shader_modes[RS::SHADER_PARTICLES].modes.push_back("collision_use_scale");
- shader_modes[RS::SHADER_PARTICLES].modes.push_back("disable_force");
- shader_modes[RS::SHADER_PARTICLES].modes.push_back("disable_velocity");
- shader_modes[RS::SHADER_PARTICLES].modes.push_back("keep_data");
+ // particles render modes
+ {
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "collision_use_scale" });
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "disable_force" });
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "disable_velocity" });
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "keep_data" });
+ }
/************ SKY **************************/
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["RADIANCE"] = constt(ShaderLanguage::TYPE_SAMPLERCUBE);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["AT_HALF_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
@@ -439,16 +414,19 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["FOG"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_SKY].functions["sky"].main_function = true;
- shader_modes[RS::SHADER_SKY].modes.push_back("use_half_res_pass");
- shader_modes[RS::SHADER_SKY].modes.push_back("use_quarter_res_pass");
- shader_modes[RS::SHADER_SKY].modes.push_back("disable_fog");
+ // sky render modes
+ {
+ shader_modes[RS::SHADER_SKY].modes.push_back({ "use_half_res_pass" });
+ shader_modes[RS::SHADER_SKY].modes.push_back({ "use_quarter_res_pass" });
+ shader_modes[RS::SHADER_SKY].modes.push_back({ "disable_fog" });
+ }
/************ FOG **************************/
shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["WORLD_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["OBJECT_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h
index 75a310a1b1..385083b670 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-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -38,7 +38,7 @@
class ShaderTypes {
struct Type {
Map<StringName, ShaderLanguage::FunctionInfo> functions;
- Vector<StringName> modes;
+ Vector<ShaderLanguage::ModeInfo> modes;
};
Map<RS::ShaderMode, Type> shader_modes;
@@ -52,7 +52,7 @@ public:
static ShaderTypes *get_singleton() { return singleton; }
const Map<StringName, ShaderLanguage::FunctionInfo> &get_functions(RS::ShaderMode p_mode) const;
- const Vector<StringName> &get_modes(RS::ShaderMode p_mode) const;
+ const Vector<ShaderLanguage::ModeInfo> &get_modes(RS::ShaderMode p_mode) const;
const Set<String> &get_types() const;
const List<String> &get_types_list() const;
diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp
index 0b8476478c..f2e74c4d78 100644
--- a/servers/rendering/shader_warnings.cpp
+++ b/servers/rendering/shader_warnings.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -61,6 +61,10 @@ String ShaderWarning::get_message() const {
return vformat("The varying '%s' is declared but never used.", subject);
case UNUSED_LOCAL_VARIABLE:
return vformat("The local variable '%s' is declared but never used.", subject);
+ case FORMATTING_ERROR:
+ return subject;
+ case DEVICE_LIMIT_EXCEEDED:
+ return vformat("The total size of the %s for this shader on this device has been exceeded (%s/%s). The shader may not work correctly.", subject, (int)extra_args[0], (int)extra_args[1]);
default:
break;
}
@@ -71,6 +75,10 @@ String ShaderWarning::get_name() const {
return get_name_from_code(code);
}
+Vector<Variant> ShaderWarning::get_extra_args() const {
+ return extra_args;
+}
+
String ShaderWarning::get_name_from_code(Code p_code) {
ERR_FAIL_INDEX_V(p_code, WARNING_MAX, String());
@@ -82,6 +90,8 @@ String ShaderWarning::get_name_from_code(Code p_code) {
"UNUSED_UNIFORM",
"UNUSED_VARYING",
"UNUSED_LOCAL_VARIABLE",
+ "FORMATTING_ERROR",
+ "DEVICE_LIMIT_EXCEEDED",
};
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
@@ -110,6 +120,8 @@ static void init_code_to_flags_map() {
code_to_flags_map->insert(ShaderWarning::UNUSED_UNIFORM, ShaderWarning::UNUSED_UNIFORM_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG);
+ code_to_flags_map->insert(ShaderWarning::FORMATTING_ERROR, ShaderWarning::FORMATTING_ERROR_FLAG);
+ code_to_flags_map->insert(ShaderWarning::DEVICE_LIMIT_EXCEEDED, ShaderWarning::DEVICE_LIMIT_EXCEEDED_FLAG);
}
ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) {
@@ -128,8 +140,8 @@ ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, b
return (CodeFlags)result;
}
-ShaderWarning::ShaderWarning(Code p_code, int p_line, const StringName &p_subject) :
- code(p_code), line(p_line), subject(p_subject) {
+ShaderWarning::ShaderWarning(Code p_code, int p_line, const StringName &p_subject, const Vector<Variant> &p_extra_args) :
+ code(p_code), line(p_line), subject(p_subject), extra_args(p_extra_args) {
}
#endif // DEBUG_ENABLED
diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h
index db872d8fb1..e309907181 100644
--- a/servers/rendering/shader_warnings.h
+++ b/servers/rendering/shader_warnings.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,6 +36,7 @@
#include "core/string/string_name.h"
#include "core/templates/list.h"
#include "core/templates/map.h"
+#include "core/variant/variant.h"
class ShaderWarning {
public:
@@ -47,6 +48,8 @@ public:
UNUSED_UNIFORM,
UNUSED_VARYING,
UNUSED_LOCAL_VARIABLE,
+ FORMATTING_ERROR,
+ DEVICE_LIMIT_EXCEEDED,
WARNING_MAX,
};
@@ -59,12 +62,15 @@ public:
UNUSED_UNIFORM_FLAG = 16U,
UNUSED_VARYING_FLAG = 32U,
UNUSED_LOCAL_VARIABLE_FLAG = 64U,
+ FORMATTING_ERROR_FLAG = 128U,
+ DEVICE_LIMIT_EXCEEDED_FLAG = 256U,
};
private:
Code code;
int line;
StringName subject;
+ Vector<Variant> extra_args;
public:
Code get_code() const;
@@ -72,12 +78,13 @@ public:
const StringName &get_subject() const;
String get_message() const;
String get_name() const;
+ Vector<Variant> get_extra_args() const;
static String get_name_from_code(Code p_code);
static Code get_code_from_name(const String &p_name);
static CodeFlags get_flags_from_codemap(const Map<Code, bool> &p_map);
- ShaderWarning(Code p_code = WARNING_MAX, int p_line = -1, const StringName &p_subject = "");
+ ShaderWarning(Code p_code = WARNING_MAX, int p_line = -1, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>());
};
#endif // DEBUG_ENABLED
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 5ebfcfd7b2..7507b44bba 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -199,11 +199,11 @@ RID RenderingServer::_make_test_cube() {
normal_points[j][i % 3] = (i >= 3 ? -1 : 1);
}
- //tri 1
+ // Tri 1
ADD_VTX(0);
ADD_VTX(1);
ADD_VTX(2);
- //tri 2
+ // Tri 2
ADD_VTX(2);
ADD_VTX(3);
ADD_VTX(0);
@@ -317,9 +317,6 @@ RID RenderingServer::get_white_texture() {
return white_texture;
}
-#define SMALL_VEC2 Vector2(0.00001, 0.00001)
-#define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001)
-
Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) {
uint8_t *vw = r_vertex_array.ptrw();
uint8_t *aw = r_attrib_array.ptrw();
@@ -333,7 +330,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
int max_bone = 0;
for (int ai = 0; ai < RS::ARRAY_MAX; ai++) {
- if (!(p_format & (1 << ai))) { // no array
+ if (!(p_format & (1 << ai))) { // No array
continue;
}
@@ -345,7 +342,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector2 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
Rect2 aabb;
{
@@ -355,7 +352,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(float) * 2);
if (i == 0) {
- aabb = Rect2(src[i], SMALL_VEC2); //must have a bit of size
+ aabb = Rect2(src[i], SMALL_VEC2); // Must have a bit of size.
} else {
aabb.expand_to(src[i]);
}
@@ -370,7 +367,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector3 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
AABB aabb;
{
@@ -505,7 +502,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RGBA8_UNORM:
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF: {
- //size 4
+ // Size 4
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -520,7 +517,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 8
+ // Size 8
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -537,7 +534,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RG_FLOAT:
case ARRAY_CUSTOM_RGB_FLOAT:
case ARRAY_CUSTOM_RGBA_FLOAT: {
- //RF
+ // RF
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<float> array = p_arrays[ai];
@@ -646,7 +643,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
}
if (p_format & RS::ARRAY_FORMAT_BONES) {
- //create AABBs for each detected bone
+ // Create AABBs for each detected bone.
int total_bones = max_bone + 1;
bool first = r_bone_aabb.size() == 0;
@@ -657,7 +654,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
if (first) {
for (int i = 0; i < total_bones; i++) {
- r_bone_aabb.write[i].size = Vector3(-1, -1, -1); //negative means unused
+ r_bone_aabb.write[i].size = Vector3(-1, -1, -1); // Negative means unused.
}
}
@@ -686,7 +683,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
ERR_FAIL_INDEX_V(idx, total_bones, ERR_INVALID_DATA);
if (bptr[idx].size.x < 0) {
- //first
+ // First
bptr[idx] = AABB(v, SMALL_VEC3);
any_valid = true;
} else {
@@ -749,7 +746,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
uint32_t *size_accum;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
- r_offsets[i] = 0; //reset
+ r_offsets[i] = 0; // Reset
if (i == RS::ARRAY_VERTEX) {
size_accum = &r_vertex_element_size;
@@ -759,7 +756,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
size_accum = &r_skin_element_size;
}
- if (!(p_format & (1 << i))) { // no array
+ if (!(p_format & (1 << i))) { // No array
continue;
}
@@ -873,7 +870,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
uint32_t format = 0;
- // validation
+ // Validation
int index_array_len = 0;
int array_len = 0;
@@ -921,10 +918,10 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
}
- ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // mandatory
+ ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // Mandatory
if (p_blend_shapes.size()) {
- //validate format for morphs
+ // Validate format for morphs.
for (int i = 0; i < p_blend_shapes.size(); i++) {
uint32_t bsformat = 0;
Array arr = p_blend_shapes[i];
@@ -939,7 +936,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
for (uint32_t i = 0; i < RS::ARRAY_CUSTOM_COUNT; ++i) {
- // include custom array format type.
+ // Include custom array format type.
if (format & (1 << (ARRAY_CUSTOM0 + i))) {
format |= (RS::ARRAY_FORMAT_CUSTOM_MASK << (RS::ARRAY_FORMAT_CUSTOM_BASE + i * RS::ARRAY_FORMAT_CUSTOM_BITS)) & p_compress_format;
}
@@ -954,7 +951,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
mesh_surface_make_offsets_from_format(format, array_len, index_array_len, offsets, vertex_element_size, attrib_element_size, skin_element_size);
uint32_t mask = (1 << ARRAY_MAX) - 1;
- format |= (~mask) & p_compress_format; //make the full format
+ format |= (~mask) & p_compress_format; // Make the full format.
int vertex_array_size = vertex_element_size * array_len;
int attrib_array_size = attrib_element_size * array_len;
@@ -1010,13 +1007,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
Vector<int> indices = p_lods[E];
ERR_CONTINUE(indices.size() == 0);
uint32_t index_count = indices.size();
- ERR_CONTINUE(index_count >= (uint32_t)index_array_len); //should be smaller..
+ ERR_CONTINUE(index_count >= (uint32_t)index_array_len); // Should be smaller..
const int *r = indices.ptr();
Vector<uint8_t> data;
if (array_len <= 65536) {
- //16 bits indices
+ // 16 bits indices
data.resize(indices.size() * 2);
uint8_t *w = data.ptrw();
uint16_t *index_ptr = (uint16_t *)w;
@@ -1024,7 +1021,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
index_ptr[i] = r[i];
}
} else {
- //32 bits indices
+ // 32 bits indices
data.resize(indices.size() * 4);
uint8_t *w = data.ptrw();
uint32_t *index_ptr = (uint32_t *)w;
@@ -1204,7 +1201,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF:
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 4
+ // Size 4
int s = type == ARRAY_CUSTOM_RGBA_HALF ? 8 : 4;
Vector<uint8_t> arr;
arr.resize(p_vertex_len * s);
@@ -1376,7 +1373,7 @@ Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_sur
Array blend_shape_array;
blend_shape_array.resize(mesh_get_blend_shape_count(p_mesh));
for (uint32_t i = 0; i < blend_shape_count; i++) {
- Vector<uint8_t> bs_data = blend_shape_data.subarray(i * divisor, (i + 1) * divisor - 1);
+ Vector<uint8_t> bs_data = blend_shape_data.slice(i * divisor, (i + 1) * divisor);
Vector<uint8_t> unused;
blend_shape_array.set(i, _get_array_from_surface(bs_format, bs_data, unused, unused, sd.vertex_count, unused, 0));
}
@@ -1472,12 +1469,12 @@ ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_dataty
case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE:
return ShaderLanguage::TYPE_SAMPLERCUBE;
default:
- return ShaderLanguage::TYPE_MAX; //invalid or not found
+ return ShaderLanguage::TYPE_MAX; // Invalid or not found.
}
}
RenderingDevice *RenderingServer::get_rendering_device() const {
- // return the rendering device we're using globally
+ // Return the rendering device we're using globally.
return RenderingDevice::get_singleton();
}
@@ -2221,8 +2218,8 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_SCALING_3D_MODE_MAX);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_DISABLED);
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); //then goes to disabled); must be manually updated
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // default
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); // Then goes to disabled); must be manually updated.
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // Default
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ALWAYS);
@@ -2277,6 +2274,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSAO);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSIL);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_PSSM_SPLITS);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DECAL_ATLAS);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SDFGI);
@@ -2553,7 +2551,8 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_set_modulate", "item", "color"), &RenderingServer::canvas_item_set_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_self_modulate", "item", "color"), &RenderingServer::canvas_item_set_self_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_draw_behind_parent", "item", "enabled"), &RenderingServer::canvas_item_set_draw_behind_parent);
- //primitives
+
+ /* Primitives */
ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width"), &RenderingServer::canvas_item_add_line, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &RenderingServer::canvas_item_add_polyline, DEFVAL(1.0), DEFVAL(false));
@@ -2704,7 +2703,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAX);
/* Free */
- ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // shouldn't conflict with Object::free()
+ ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // Shouldn't conflict with Object::free().
/* Misc */
@@ -2897,6 +2896,18 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/environment/ssao/fadeout_to", 300.0);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssao/fadeout_to", PropertyInfo(Variant::FLOAT, "rendering/environment/ssao/fadeout_to", PROPERTY_HINT_RANGE, "64,65536,0.1,or_greater"));
+ GLOBAL_DEF("rendering/environment/ssil/quality", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssil/quality", PropertyInfo(Variant::INT, "rendering/environment/ssil/quality", PROPERTY_HINT_ENUM, "Very Low (Fast),Low (Fast),Medium (Average),High (Slow),Ultra (Custom)"));
+ GLOBAL_DEF("rendering/environment/ssil/half_size", true);
+ GLOBAL_DEF("rendering/environment/ssil/adaptive_target", 0.5);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssil/adaptive_target", PropertyInfo(Variant::FLOAT, "rendering/environment/ssil/adaptive_target", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
+ GLOBAL_DEF("rendering/environment/ssil/blur_passes", 4);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssil/blur_passes", PropertyInfo(Variant::INT, "rendering/environment/ssil/blur_passes", PROPERTY_HINT_RANGE, "0,6"));
+ GLOBAL_DEF("rendering/environment/ssil/fadeout_from", 50.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssil/fadeout_from", PropertyInfo(Variant::FLOAT, "rendering/environment/ssil/fadeout_from", PROPERTY_HINT_RANGE, "0.0,512,0.1,or_greater"));
+ GLOBAL_DEF("rendering/environment/ssil/fadeout_to", 300.0);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/environment/ssil/fadeout_to", PropertyInfo(Variant::FLOAT, "rendering/environment/ssil/fadeout_to", PROPERTY_HINT_RANGE, "64,65536,0.1,or_greater"));
+
GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/enabled", true);
GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/amount", 0.25);
GLOBAL_DEF("rendering/anti_aliasing/screen_space_roughness_limiter/limit", 0.18);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 85f92bc003..51762ac92b 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -55,6 +55,9 @@ class RenderingServer : public Object {
RendererThreadPool *thread_pool = nullptr;
+ const Vector2 SMALL_VEC2 = Vector2(CMP_EPSILON, CMP_EPSILON);
+ const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON);
+
protected:
RID _make_test_cube();
void _free_internal_rids();
@@ -108,7 +111,7 @@ public:
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0;
- //these two APIs can be used together or in combination with the others.
+ // 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(TextureLayeredType p_layered_type) = 0;
virtual RID texture_3d_placeholder_create() = 0;
@@ -210,18 +213,18 @@ public:
enum ArrayType {
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
- ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored
- ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal
+ ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
+ ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
ARRAY_COLOR = 3, // RGBA8
ARRAY_TEX_UV = 4, // RG32F
ARRAY_TEX_UV2 = 5, // RG32F
- ARRAY_CUSTOM0 = 6, // depends on ArrayCustomFormat
+ ARRAY_CUSTOM0 = 6, // Depends on ArrayCustomFormat.
ARRAY_CUSTOM1 = 7,
ARRAY_CUSTOM2 = 8,
ARRAY_CUSTOM3 = 9,
ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights)
ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights)
- ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF
+ ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF.
ARRAY_MAX = 13
};
@@ -243,7 +246,7 @@ public:
enum ArrayFormat {
/* ARRAY FORMAT FLAGS */
- ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory
+ ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // Mandatory
ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL,
ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT,
ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR,
@@ -287,9 +290,9 @@ public:
PrimitiveType primitive = PRIMITIVE_MAX;
uint32_t format = 0;
- Vector<uint8_t> vertex_data; // vertex, normal, tangent (change with skinning, blendshape)
- Vector<uint8_t> attribute_data; // color,uv, uv2, custom0-3
- Vector<uint8_t> skin_data; // bone index, bone weight
+ Vector<uint8_t> vertex_data; // Vertex, Normal, Tangent (change with skinning, blendshape).
+ Vector<uint8_t> attribute_data; // Color, UV, UV2, Custom0-3.
+ Vector<uint8_t> skin_data; // Bone index, Bone weight.
uint32_t vertex_count = 0;
Vector<uint8_t> index_data;
uint32_t index_count = 0;
@@ -452,7 +455,7 @@ public:
virtual void light_set_bake_mode(RID p_light, LightBakeMode p_bake_mode) = 0;
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0;
- // omni light
+ // Omni light
enum LightOmniShadowMode {
LIGHT_OMNI_SHADOW_DUAL_PARABOLOID,
LIGHT_OMNI_SHADOW_CUBE,
@@ -460,7 +463,7 @@ public:
virtual void light_omni_set_shadow_mode(RID p_light, LightOmniShadowMode p_mode) = 0;
- // directional light
+ // Directional light
enum LightDirectionalShadowMode {
LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL,
LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS,
@@ -671,7 +674,7 @@ public:
virtual AABB particles_get_current_aabb(RID p_particles) = 0;
- virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; //this is only used for 2D, in 3D it's automatic
+ virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; // This is only used for 2D, in 3D it's automatic.
/* PARTICLES COLLISION API */
@@ -689,16 +692,16 @@ public:
virtual void particles_collision_set_collision_type(RID p_particles_collision, 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, real_t 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_sphere_radius(RID p_particles_collision, real_t 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, real_t p_strength) = 0;
virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) = 0;
virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t 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_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_height_field_update(RID p_particles_collision) = 0; // For SDF and vector field.
- enum ParticlesCollisionHeightfieldResolution { //longest axis resolution
+ enum ParticlesCollisionHeightfieldResolution { // Longest axis resolution.
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_256,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_512,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024,
@@ -708,7 +711,7 @@ public:
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX,
};
- virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field
+ virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; // For SDF and vector field.
/* FOG VOLUME API */
@@ -750,7 +753,7 @@ public:
/* VIEWPORT API */
enum CanvasItemTextureFilter {
- CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_FILTER_NEAREST,
CANVAS_ITEM_TEXTURE_FILTER_LINEAR,
CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS,
@@ -761,7 +764,7 @@ public:
};
enum CanvasItemTextureRepeat {
- CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_REPEAT_DISABLED,
CANVAS_ITEM_TEXTURE_REPEAT_ENABLED,
CANVAS_ITEM_TEXTURE_REPEAT_MIRROR,
@@ -791,8 +794,8 @@ public:
enum ViewportUpdateMode {
VIEWPORT_UPDATE_DISABLED,
- VIEWPORT_UPDATE_ONCE, //then goes to disabled, must be manually updated
- VIEWPORT_UPDATE_WHEN_VISIBLE, // default
+ VIEWPORT_UPDATE_ONCE, // Then goes to disabled, must be manually updated.
+ VIEWPORT_UPDATE_WHEN_VISIBLE, // Default
VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE,
VIEWPORT_UPDATE_ALWAYS
};
@@ -910,6 +913,7 @@ public:
VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS,
VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE,
VIEWPORT_DEBUG_DRAW_SSAO,
+ VIEWPORT_DEBUG_DRAW_SSIL,
VIEWPORT_DEBUG_DRAW_PSSM_SPLITS,
VIEWPORT_DEBUG_DRAW_DECAL_ATLAS,
VIEWPORT_DEBUG_DRAW_SDFGI,
@@ -1026,6 +1030,18 @@ public:
virtual void environment_set_ssao_quality(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_ssil(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_sharpness, float p_normal_rejection) = 0;
+
+ enum EnvironmentSSILQuality {
+ ENV_SSIL_QUALITY_VERY_LOW,
+ ENV_SSIL_QUALITY_LOW,
+ ENV_SSIL_QUALITY_MEDIUM,
+ ENV_SSIL_QUALITY_HIGH,
+ ENV_SSIL_QUALITY_ULTRA,
+ };
+
+ virtual void environment_set_ssil_quality(EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0;
+
enum EnvironmentSDFGICascades {
ENV_SDFGI_CASCADES_4,
ENV_SDFGI_CASCADES_6,
@@ -1171,7 +1187,7 @@ public:
virtual void instance_set_ignore_culling(RID p_instance, bool p_enabled) = 0;
- // don't use these in a game!
+ // 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;
@@ -1245,7 +1261,7 @@ public:
virtual void canvas_texture_set_channel(RID p_canvas_texture, 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;
- //takes effect only for new draw commands
+ // Takes effect only for new draw commands.
virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, CanvasItemTextureFilter p_filter) = 0;
virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, CanvasItemTextureRepeat p_repeat) = 0;
@@ -1443,7 +1459,7 @@ public:
/* FREE */
- virtual void free(RID p_rid) = 0; ///< free RIDs associated with the rendering server
+ virtual void free(RID p_rid) = 0; // Free RIDs associated with the rendering server.
/* EVENT QUEUING */
@@ -1529,7 +1545,7 @@ public:
virtual ~RenderingServer();
private:
- //binder helpers
+ // Binder helpers
RID _texture_2d_layered_create(const TypedArray<Image> &p_layers, TextureLayeredType p_layered_type);
RID _texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data);
void _texture_3d_update(RID p_texture, const TypedArray<Image> &p_data);
@@ -1543,7 +1559,7 @@ private:
void _particles_set_trail_bind_poses(RID p_particles, const TypedArray<Transform3D> &p_bind_poses);
};
-// make variant understand the enums
+// Make variant understand the enums.
VARIANT_ENUM_CAST(RenderingServer::TextureLayeredType);
VARIANT_ENUM_CAST(RenderingServer::CubeMapLayer);
VARIANT_ENUM_CAST(RenderingServer::ShaderMode);
diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h
index 95d2e2254e..2c4aab0784 100644
--- a/servers/server_wrap_mt_common.h
+++ b/servers/server_wrap_mt_common.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index d6d98b4f8f..2b0510680e 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1003,7 +1003,7 @@ bool TextServerExtension::shaped_text_add_string(RID p_shaped, const String &p_t
return false;
}
-bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align, int p_length) {
+bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align, int p_length) {
bool ret;
if (GDVIRTUAL_CALL(_shaped_text_add_object, p_shaped, p_key, p_size, p_inline_align, p_length, ret)) {
return ret;
@@ -1011,7 +1011,7 @@ bool TextServerExtension::shaped_text_add_object(RID p_shaped, Variant p_key, co
return false;
}
-bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align) {
+bool TextServerExtension::shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align) {
bool ret;
if (GDVIRTUAL_CALL(_shaped_text_resize_object, p_shaped, p_key, p_size, p_inline_align, ret)) {
return ret;
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index a2dbd25e05..5c97401118 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -337,11 +337,11 @@ public:
GDVIRTUAL1RC(bool, _shaped_text_get_preserve_control, RID);
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") override;
- virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) override;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) override;
+ virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) override;
+ virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
GDVIRTUAL6R(bool, _shaped_text_add_string, RID, const String &, const Array &, int, const Dictionary &, const String &);
- GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlign, int);
- GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlign);
+ GDVIRTUAL5R(bool, _shaped_text_add_object, RID, Variant, const Size2 &, InlineAlignment, int);
+ GDVIRTUAL4R(bool, _shaped_text_resize_object, RID, Variant, const Size2 &, InlineAlignment);
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const override;
virtual RID shaped_text_get_parent(RID p_shaped) const override;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 3b71dc1d92..d547bcc75e 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -360,8 +360,8 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_get_preserve_control", "shaped"), &TextServer::shaped_text_get_preserve_control);
ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""));
- ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGN_CENTER), DEFVAL(1));
- ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGN_CENTER));
+ ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
ClassDB::bind_method(D_METHOD("shaped_text_substr", "shaped", "start", "length"), &TextServer::shaped_text_substr);
ClassDB::bind_method(D_METHOD("shaped_text_get_parent", "shaped"), &TextServer::shaped_text_get_parent);
@@ -649,13 +649,13 @@ PackedInt32Array TextServer::shaped_text_get_line_breaks_adv(RID p_shaped, const
return lines;
}
-PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, real_t p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const {
+PackedInt32Array TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_width, int p_start, uint16_t /*TextBreakFlag*/ p_break_flags) const {
PackedInt32Array lines;
const_cast<TextServer *>(this)->shaped_text_update_breaks(p_shaped);
const Vector2i &range = shaped_text_get_range(p_shaped);
- real_t width = 0.f;
+ float width = 0.f;
int line_start = MAX(p_start, range.x);
int last_safe_break = -1;
int word_count = 0;
@@ -1035,9 +1035,9 @@ Vector<Vector2> TextServer::shaped_text_get_selection(RID p_shaped, int p_start,
return ranges;
}
-int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) const {
+int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, float p_coords) const {
// Exact grapheme hit test, return -1 if missed.
- real_t off = 0.0f;
+ float off = 0.0f;
int v_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
@@ -1053,7 +1053,7 @@ int TextServer::shaped_text_hit_test_grapheme(RID p_shaped, real_t p_coords) con
return -1;
}
-int TextServer::shaped_text_hit_test_position(RID p_shaped, real_t p_coords) const {
+int TextServer::shaped_text_hit_test_position(RID p_shaped, float p_coords) const {
int v_size = shaped_text_get_glyph_count(p_shaped);
const Glyph *glyphs = shaped_text_get_glyphs(p_shaped);
@@ -1165,7 +1165,7 @@ int TextServer::shaped_text_prev_grapheme_pos(RID p_shaped, int p_pos) const {
return p_pos;
}
-void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, const Color &p_color) const {
+void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, const Color &p_color) const {
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
bool hex_codes = shaped_text_get_preserve_control(p_shaped) || shaped_text_get_preserve_invalid(p_shaped);
@@ -1262,7 +1262,7 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p
}
}
-void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, real_t p_clip_l, real_t p_clip_r, int p_outline_size, const Color &p_color) const {
+void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vector2 &p_pos, float p_clip_l, float p_clip_r, int p_outline_size, const Color &p_color) const {
TextServer::Orientation orientation = shaped_text_get_orientation(p_shaped);
bool rtl = (shaped_text_get_direction(p_shaped) == DIRECTION_RTL);
diff --git a/servers/text_server.h b/servers/text_server.h
index 5c994feaae..e9c5248866 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -170,7 +170,7 @@ protected:
struct EmbeddedObject {
int pos = 0;
- InlineAlign inline_align = INLINE_ALIGN_CENTER;
+ InlineAlignment inline_align = INLINE_ALIGNMENT_CENTER;
Rect2 rect;
};
Map<Variant, EmbeddedObject> objects;
@@ -383,8 +383,8 @@ public:
virtual bool shaped_text_get_preserve_control(RID p_shaped) const = 0;
virtual bool shaped_text_add_string(RID p_shaped, const String &p_text, const Vector<RID> &p_fonts, int p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "") = 0;
- virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER, int p_length = 1) = 0;
- virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlign p_inline_align = INLINE_ALIGN_CENTER) = 0;
+ virtual bool shaped_text_add_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int p_length = 1) = 0;
+ virtual bool shaped_text_resize_object(RID p_shaped, Variant p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0;
virtual RID shaped_text_substr(RID p_shaped, int p_start, int p_length) const = 0; // Copy shaped substring (e.g. line break) without reshaping, but correctly reordered, preservers range.
virtual RID shaped_text_get_parent(RID p_shaped) const = 0;
diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp
index ca11df439c..758f2416ec 100644
--- a/servers/xr/xr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h
index b489481f75..03563026c8 100644
--- a/servers/xr/xr_interface.h
+++ b/servers/xr/xr_interface.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp
index 80576ac607..9dae3b162d 100644
--- a/servers/xr/xr_interface_extension.cpp
+++ b/servers/xr/xr_interface_extension.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h
index 763526de96..e22ec2b872 100644
--- a/servers/xr/xr_interface_extension.h
+++ b/servers/xr/xr_interface_extension.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_pose.cpp b/servers/xr/xr_pose.cpp
index 0d05e62b46..ab6eb042c9 100644
--- a/servers/xr/xr_pose.cpp
+++ b/servers/xr/xr_pose.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_pose.h b/servers/xr/xr_pose.h
index 223e95ddfe..8c1fc63360 100644
--- a/servers/xr/xr_pose.h
+++ b/servers/xr/xr_pose.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp
index 1313a91172..74907a5675 100644
--- a/servers/xr/xr_positional_tracker.cpp
+++ b/servers/xr/xr_positional_tracker.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h
index 69eb105b5a..895bcab215 100644
--- a/servers/xr/xr_positional_tracker.h
+++ b/servers/xr/xr_positional_tracker.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index 959288497d..69f4c69b53 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/servers/xr_server.h b/servers/xr_server.h
index 48d73cac9a..824a42ed31 100644
--- a/servers/xr_server.h
+++ b/servers/xr_server.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */