diff options
Diffstat (limited to 'servers')
139 files changed, 2028 insertions, 1368 deletions
diff --git a/servers/audio/audio_effect.cpp b/servers/audio/audio_effect.cpp index b9eca14a4c..f38d0adfb2 100644 --- a/servers/audio/audio_effect.cpp +++ b/servers/audio/audio_effect.cpp @@ -30,5 +30,36 @@ #include "audio_effect.h" +void AudioEffectInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) { + if (GDVIRTUAL_REQUIRED_CALL(_process, p_src_frames, p_dst_frames, p_frame_count)) { + return; + } +} +bool AudioEffectInstance::process_silence() const { + bool ret; + if (GDVIRTUAL_CALL(_process_silence, ret)) { + return ret; + } + return false; +} + +void AudioEffectInstance::_bind_methods() { + GDVIRTUAL_BIND(_process, "src_buffer", "dst_buffer", "frame_count"); + GDVIRTUAL_BIND(_process_silence); +} + +//// + +Ref<AudioEffectInstance> AudioEffect::instantiate() { + Ref<AudioEffectInstance> ret; + if (GDVIRTUAL_REQUIRED_CALL(_instantiate, ret)) { + return ret; + } + return Ref<AudioEffectInstance>(); +} +void AudioEffect::_bind_methods() { + GDVIRTUAL_BIND(_instantiate); +} + AudioEffect::AudioEffect() { } diff --git a/servers/audio/audio_effect.h b/servers/audio/audio_effect.h index 00a5d6c004..3a0578679d 100644 --- a/servers/audio/audio_effect.h +++ b/servers/audio/audio_effect.h @@ -33,20 +33,32 @@ #include "core/io/resource.h" #include "core/math/audio_frame.h" +#include "core/object/gdvirtual.gen.inc" +#include "core/object/script_language.h" +#include "core/variant/native_ptr.h" class AudioEffectInstance : public RefCounted { GDCLASS(AudioEffectInstance, RefCounted); +protected: + GDVIRTUAL3(_process, GDNativeConstPtr<AudioFrame>, GDNativePtr<AudioFrame>, int) + GDVIRTUAL0RC(bool, _process_silence) + static void _bind_methods(); + public: - virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) = 0; - virtual bool process_silence() const { return false; } + virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count); + virtual bool process_silence() const; }; class AudioEffect : public Resource { GDCLASS(AudioEffect, Resource); +protected: + GDVIRTUAL0R(Ref<AudioEffectInstance>, _instantiate) + static void _bind_methods(); + public: - virtual Ref<AudioEffectInstance> instantiate() = 0; + virtual Ref<AudioEffectInstance> instantiate(); AudioEffect(); }; diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp index 39060286a4..1ebd57fa7f 100644 --- a/servers/audio/audio_stream.cpp +++ b/servers/audio/audio_stream.cpp @@ -76,10 +76,10 @@ void AudioStreamPlayback::seek(float p_time) { int AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { int ret; - if (GDVIRTUAL_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret)) { + if (GDVIRTUAL_REQUIRED_CALL(_mix, p_buffer, p_rate_scale, p_frames, ret)) { return ret; } - WARN_PRINT_ONCE("AudioStreamPlayback::mix unimplemented!"); + return 0; } @@ -94,7 +94,7 @@ void AudioStreamPlayback::_bind_methods() { } ////////////////////////////// -void AudioStreamPlaybackResampled::_begin_resample() { +void AudioStreamPlaybackResampled::begin_resample() { //clear cubic interpolation history internal_buffer[0] = AudioFrame(0.0, 0.0); internal_buffer[1] = AudioFrame(0.0, 0.0); @@ -105,6 +105,30 @@ void AudioStreamPlaybackResampled::_begin_resample() { mix_offset = 0; } +int AudioStreamPlaybackResampled::_mix_internal(AudioFrame *p_buffer, int p_frames) { + int ret; + if (GDVIRTUAL_REQUIRED_CALL(_mix_resampled, p_buffer, p_frames, ret)) { + return ret; + } + + return 0; +} +float AudioStreamPlaybackResampled::get_stream_sampling_rate() { + float ret; + if (GDVIRTUAL_REQUIRED_CALL(_get_stream_sampling_rate, ret)) { + return ret; + } + + return 0; +} + +void AudioStreamPlaybackResampled::_bind_methods() { + ClassDB::bind_method(D_METHOD("begin_resample"), &AudioStreamPlaybackResampled::begin_resample); + + GDVIRTUAL_BIND(_mix_resampled, "dst_buffer", "frame_count"); + GDVIRTUAL_BIND(_get_stream_sampling_rate); +} + int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) { float target_rate = AudioServer::get_singleton()->get_mix_rate(); float playback_speed_scale = AudioServer::get_singleton()->get_playback_speed_scale(); @@ -200,6 +224,7 @@ bool AudioStream::is_monophonic() const { void AudioStream::_bind_methods() { ClassDB::bind_method(D_METHOD("get_length"), &AudioStream::get_length); ClassDB::bind_method(D_METHOD("is_monophonic"), &AudioStream::is_monophonic); + ClassDB::bind_method(D_METHOD("instance_playback"), &AudioStream::instance_playback); GDVIRTUAL_BIND(_instance_playback); GDVIRTUAL_BIND(_get_stream_name); GDVIRTUAL_BIND(_get_length); @@ -314,7 +339,7 @@ void AudioStreamPlaybackMicrophone::start(float p_from_pos) { if (AudioDriver::get_singleton()->capture_start() == OK) { active = true; - _begin_resample(); + begin_resample(); } } diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index ce9bcabb9c..55031dec2c 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -81,10 +81,15 @@ class AudioStreamPlaybackResampled : public AudioStreamPlayback { uint64_t mix_offset; protected: - void _begin_resample(); + void begin_resample(); // Returns the number of frames that were mixed. - virtual int _mix_internal(AudioFrame *p_buffer, int p_frames) = 0; - virtual float get_stream_sampling_rate() = 0; + virtual int _mix_internal(AudioFrame *p_buffer, int p_frames); + virtual float get_stream_sampling_rate(); + + GDVIRTUAL2R(int, _mix_resampled, GDNativePtr<AudioFrame>, int) + GDVIRTUAL0RC(float, _get_stream_sampling_rate) + + static void _bind_methods(); public: virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override; diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp index bddd235204..1909ab6eae 100644 --- a/servers/audio/effects/audio_effect_delay.cpp +++ b/servers/audio/effects/audio_effect_delay.cpp @@ -54,15 +54,12 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au float tap_1_level_f = base->tap_1_active ? Math::db2linear(base->tap_1_level) : 0.0; int tap_1_delay_frames = int((base->tap_1_delay_ms / 1000.0) * mix_rate); - ; float tap_2_level_f = base->tap_2_active ? Math::db2linear(base->tap_2_level) : 0.0; int tap_2_delay_frames = int((base->tap_2_delay_ms / 1000.0) * mix_rate); - ; float feedback_level_f = base->feedback_active ? Math::db2linear(base->feedback_level) : 0.0; unsigned int feedback_delay_frames = int((base->feedback_delay_ms / 1000.0) * mix_rate); - ; AudioFrame tap1_vol = AudioFrame(tap_1_level_f, tap_1_level_f); diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp index 757edd6d43..c81efc55e2 100644 --- a/servers/audio/effects/audio_effect_stereo_enhance.cpp +++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp @@ -61,7 +61,6 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A //r is delayed r = delay_ringbuff[(ringbuff_pos - delay_frames) & ringbuff_mask]; - ; } p_dst_frames[i].l = l; diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp index 6c917f3eb6..a3d615b925 100644 --- a/servers/audio/effects/audio_stream_generator.cpp +++ b/servers/audio/effects/audio_stream_generator.cpp @@ -169,7 +169,7 @@ float AudioStreamGeneratorPlayback::get_stream_sampling_rate() { void AudioStreamGeneratorPlayback::start(float p_from_pos) { if (mixed == 0.0) { - _begin_resample(); + begin_resample(); } skips = 0; active = true; diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index f00b8077d1..9d83e5cacc 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1731,6 +1731,10 @@ void AudioServer::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "bus_count"), "set_bus_count", "get_bus_count"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "device"), "set_device", "get_device"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "capture_device"), "capture_set_device", "capture_get_device"); + // The default value may be set to an empty string by the platform-specific audio driver. + // Override for class reference generation purposes. + ADD_PROPERTY_DEFAULT("capture_device", "Default"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "playback_speed_scale"), "set_playback_speed_scale", "get_playback_speed_scale"); ADD_SIGNAL(MethodInfo("bus_layout_changed")); diff --git a/servers/camera/camera_feed.cpp b/servers/camera/camera_feed.cpp index 3aab995857..624c06ecf1 100644 --- a/servers/camera/camera_feed.cpp +++ b/servers/camera/camera_feed.cpp @@ -33,7 +33,7 @@ #include "servers/rendering_server.h" void CameraFeed::_bind_methods() { - // The setters prefixed with _ are only exposed so we can have feeds through GDNative! + // The setters prefixed with _ are only exposed so we can have feeds through GDExtension! // They should not be called by the end user. ClassDB::bind_method(D_METHOD("get_id"), &CameraFeed::get_id); diff --git a/servers/display_server.cpp b/servers/display_server.cpp index d880df2a9b..819c151087 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -204,6 +204,10 @@ void DisplayServer::delete_sub_window(WindowID p_id) { ERR_FAIL_MSG("Sub-windows not supported by this display server."); } +void DisplayServer::window_set_exclusive(WindowID p_window, bool p_exclusive) { + // Do nothing, if not supported. +} + void DisplayServer::window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window) { ERR_FAIL_MSG("Mouse passthrough not supported by this display server."); } @@ -395,6 +399,9 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("delete_sub_window", "window_id"), &DisplayServer::delete_sub_window); ClassDB::bind_method(D_METHOD("window_get_native_handle", "handle_type", "window_id"), &DisplayServer::window_get_native_handle, DEFVAL(MAIN_WINDOW_ID)); + ClassDB::bind_method(D_METHOD("window_get_active_popup"), &DisplayServer::window_get_active_popup); + ClassDB::bind_method(D_METHOD("window_set_popup_safe_rect", "window", "rect"), &DisplayServer::window_set_popup_safe_rect); + ClassDB::bind_method(D_METHOD("window_get_popup_safe_rect", "window"), &DisplayServer::window_get_popup_safe_rect); ClassDB::bind_method(D_METHOD("window_set_title", "title", "window_id"), &DisplayServer::window_set_title, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_mouse_passthrough", "region", "window_id"), &DisplayServer::window_set_mouse_passthrough, DEFVAL(MAIN_WINDOW_ID)); @@ -436,6 +443,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("window_can_draw", "window_id"), &DisplayServer::window_can_draw, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_transient", "window_id", "parent_window_id"), &DisplayServer::window_set_transient); + ClassDB::bind_method(D_METHOD("window_set_exclusive", "window_id", "exclusive"), &DisplayServer::window_set_exclusive); ClassDB::bind_method(D_METHOD("window_set_ime_active", "active", "window_id"), &DisplayServer::window_set_ime_active, DEFVAL(MAIN_WINDOW_ID)); ClassDB::bind_method(D_METHOD("window_set_ime_position", "position", "window_id"), &DisplayServer::window_set_ime_position, DEFVAL(MAIN_WINDOW_ID)); @@ -446,7 +454,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("ime_get_selection"), &DisplayServer::ime_get_selection); ClassDB::bind_method(D_METHOD("ime_get_text"), &DisplayServer::ime_get_text); - ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "multiline", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(false), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "multiline", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2()), DEFVAL(false), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("virtual_keyboard_hide"), &DisplayServer::virtual_keyboard_hide); ClassDB::bind_method(D_METHOD("virtual_keyboard_get_height"), &DisplayServer::virtual_keyboard_get_height); @@ -547,6 +555,7 @@ void DisplayServer::_bind_methods() { BIND_ENUM_CONSTANT(WINDOW_FLAG_ALWAYS_ON_TOP); BIND_ENUM_CONSTANT(WINDOW_FLAG_TRANSPARENT); BIND_ENUM_CONSTANT(WINDOW_FLAG_NO_FOCUS); + BIND_ENUM_CONSTANT(WINDOW_FLAG_POPUP); BIND_ENUM_CONSTANT(WINDOW_FLAG_MAX); BIND_ENUM_CONSTANT(WINDOW_EVENT_MOUSE_ENTER); diff --git a/servers/display_server.h b/servers/display_server.h index 19bb111094..67dbab0924 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -175,7 +175,7 @@ public: SCREEN_OF_MAIN_WINDOW = -1 }; - const float SCREEN_REFRESH_RATE_FALLBACK = 60.0; // Returned by screen_get_refresh_rate if the method fails. Most screens are 60hz as of 2022. + const float SCREEN_REFRESH_RATE_FALLBACK = -1.0; // Returned by screen_get_refresh_rate if the method fails. virtual int get_screen_count() const = 0; virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const = 0; @@ -226,6 +226,7 @@ public: WINDOW_FLAG_ALWAYS_ON_TOP, WINDOW_FLAG_TRANSPARENT, WINDOW_FLAG_NO_FOCUS, + WINDOW_FLAG_POPUP, WINDOW_FLAG_MAX, }; @@ -235,13 +236,18 @@ public: WINDOW_FLAG_BORDERLESS_BIT = (1 << WINDOW_FLAG_BORDERLESS), WINDOW_FLAG_ALWAYS_ON_TOP_BIT = (1 << WINDOW_FLAG_ALWAYS_ON_TOP), WINDOW_FLAG_TRANSPARENT_BIT = (1 << WINDOW_FLAG_TRANSPARENT), - WINDOW_FLAG_NO_FOCUS_BIT = (1 << WINDOW_FLAG_NO_FOCUS) + WINDOW_FLAG_NO_FOCUS_BIT = (1 << WINDOW_FLAG_NO_FOCUS), + WINDOW_FLAG_POPUP_BIT = (1 << WINDOW_FLAG_POPUP), }; virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()); virtual void show_window(WindowID p_id); virtual void delete_sub_window(WindowID p_id); + virtual WindowID window_get_active_popup() const { return INVALID_WINDOW_ID; }; + virtual void window_set_popup_safe_rect(WindowID p_window, const Rect2i &p_rect){}; + virtual Rect2i window_get_popup_safe_rect(WindowID p_window) const { return Rect2i(); }; + virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const; virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0; @@ -277,6 +283,7 @@ public: virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual void window_set_transient(WindowID p_window, WindowID p_parent) = 0; + virtual void window_set_exclusive(WindowID p_window, bool p_exclusive); virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) = 0; virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const = 0; diff --git a/servers/physics_2d/godot_body_pair_2d.cpp b/servers/physics_2d/godot_body_pair_2d.cpp index 1986191cc3..2bf1e5a1d4 100644 --- a/servers/physics_2d/godot_body_pair_2d.cpp +++ b/servers/physics_2d/godot_body_pair_2d.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "godot_body_pair_2d.h" + #include "godot_collision_solver_2d.h" #include "godot_space_2d.h" @@ -303,7 +304,7 @@ bool GodotBodyPair2D::setup(real_t p_step) { bool valid = false; for (int i = 0; i < contact_count; i++) { Contact &c = contacts[i]; - if (c.normal.dot(direction) > -CMP_EPSILON) { //greater (normal inverted) + if (c.normal.dot(direction) > -CMP_EPSILON) { // Greater (normal inverted). continue; } valid = true; @@ -321,7 +322,7 @@ bool GodotBodyPair2D::setup(real_t p_step) { bool valid = false; for (int i = 0; i < contact_count; i++) { Contact &c = contacts[i]; - if (c.normal.dot(direction) < CMP_EPSILON) { //less (normal ok) + if (c.normal.dot(direction) < CMP_EPSILON) { // Less (normal ok). continue; } valid = true; diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp index 5a96dae8ca..06f035a506 100644 --- a/servers/physics_2d/godot_broad_phase_2d_bvh.cpp +++ b/servers/physics_2d/godot_broad_phase_2d_bvh.cpp @@ -32,7 +32,9 @@ #include "godot_collision_object_2d.h" GodotBroadPhase2D::ID GodotBroadPhase2DBVH::create(GodotCollisionObject2D *p_object, int p_subindex, const Rect2 &p_aabb, bool p_static) { - ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + ID oid = bvh.create(p_object, true, tree_id, tree_collision_mask, p_aabb, p_subindex); // Pair everything, don't care? return oid + 1; } @@ -41,8 +43,9 @@ void GodotBroadPhase2DBVH::move(ID p_id, const Rect2 &p_aabb) { } void GodotBroadPhase2DBVH::set_static(ID p_id, bool p_static) { - GodotCollisionObject2D *it = bvh.get(p_id - 1); - bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + bvh.set_tree(p_id - 1, tree_id, tree_collision_mask, false); } void GodotBroadPhase2DBVH::remove(ID p_id) { @@ -56,7 +59,8 @@ GodotCollisionObject2D *GodotBroadPhase2DBVH::get_object(ID p_id) const { } bool GodotBroadPhase2DBVH::is_static(ID p_id) const { - return !bvh.is_pairable(p_id - 1); + uint32_t tree_id = bvh.get_tree_id(p_id - 1); + return tree_id == 0; } int GodotBroadPhase2DBVH::get_subindex(ID p_id) const { @@ -64,11 +68,11 @@ int GodotBroadPhase2DBVH::get_subindex(ID p_id) const { } int GodotBroadPhase2DBVH::cull_segment(const Vector2 &p_from, const Vector2 &p_to, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); + return bvh.cull_segment(p_from, p_to, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } int GodotBroadPhase2DBVH::cull_aabb(const Rect2 &p_aabb, GodotCollisionObject2D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); + return bvh.cull_aabb(p_aabb, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } void *GodotBroadPhase2DBVH::_pair_callback(void *self, uint32_t p_A, GodotCollisionObject2D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject2D *p_object_B, int subindex_B) { diff --git a/servers/physics_2d/godot_broad_phase_2d_bvh.h b/servers/physics_2d/godot_broad_phase_2d_bvh.h index d77e0574eb..b11ad0e75e 100644 --- a/servers/physics_2d/godot_broad_phase_2d_bvh.h +++ b/servers/physics_2d/godot_broad_phase_2d_bvh.h @@ -38,7 +38,34 @@ #include "core/math/vector2.h" class GodotBroadPhase2DBVH : public GodotBroadPhase2D { - BVH_Manager<GodotCollisionObject2D, true, 128, Rect2, Vector2> bvh; + template <class T> + class UserPairTestFunction { + public: + static bool user_pair_check(const T *p_a, const T *p_b) { + // return false if no collision, decided by masks etc + return p_a->interacts_with(p_b); + } + }; + + template <class T> + class UserCullTestFunction { + public: + static bool user_cull_check(const T *p_a, const T *p_b) { + return true; + } + }; + + enum Tree { + TREE_STATIC = 0, + TREE_DYNAMIC = 1, + }; + + enum TreeFlag { + TREE_FLAG_STATIC = 1 << TREE_STATIC, + TREE_FLAG_DYNAMIC = 1 << TREE_DYNAMIC, + }; + + BVH_Manager<GodotCollisionObject2D, 2, true, 128, UserPairTestFunction<GodotCollisionObject2D>, UserCullTestFunction<GodotCollisionObject2D>, Rect2, Vector2> bvh; static void *_pair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int); static void _unpair_callback(void *, uint32_t, GodotCollisionObject2D *, int, uint32_t, GodotCollisionObject2D *, int, void *); diff --git a/servers/physics_2d/godot_collision_object_2d.h b/servers/physics_2d/godot_collision_object_2d.h index 1e9baad8d9..19d6e91561 100644 --- a/servers/physics_2d/godot_collision_object_2d.h +++ b/servers/physics_2d/godot_collision_object_2d.h @@ -180,7 +180,7 @@ public: return p_other->collision_layer & collision_mask; } - _FORCE_INLINE_ bool interacts_with(GodotCollisionObject2D *p_other) const { + _FORCE_INLINE_ bool interacts_with(const GodotCollisionObject2D *p_other) const { return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask; } diff --git a/servers/physics_2d/godot_collision_solver_2d_sat.cpp b/servers/physics_2d/godot_collision_solver_2d_sat.cpp index a965795bee..ded3ff356b 100644 --- a/servers/physics_2d/godot_collision_solver_2d_sat.cpp +++ b/servers/physics_2d/godot_collision_solver_2d_sat.cpp @@ -41,10 +41,6 @@ struct _CollectorCallback2D { Vector2 *sep_axis = nullptr; _FORCE_INLINE_ void call(const Vector2 &p_point_A, const Vector2 &p_point_B) { - /* - if (normal.dot(p_point_A) >= normal.dot(p_point_B)) - return; - */ if (swap) { callback(p_point_B, p_point_A, userdata); } else { diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp index 5e099e27ec..a9b499c6b5 100644 --- a/servers/physics_2d/godot_physics_server_2d.cpp +++ b/servers/physics_2d/godot_physics_server_2d.cpp @@ -1188,14 +1188,6 @@ void GodotPhysicsServer2D::free(RID p_rid) { } else if (body_owner.owns(p_rid)) { GodotBody2D *body = body_owner.get_or_null(p_rid); - /* - if (body->get_state_query()) - _clear_query(body->get_state_query()); - - if (body->get_direct_state_query()) - _clear_query(body->get_direct_state_query()); - */ - body_set_space(p_rid, RID()); while (body->get_shape_count()) { @@ -1208,11 +1200,6 @@ void GodotPhysicsServer2D::free(RID p_rid) { } else if (area_owner.owns(p_rid)) { GodotArea2D *area = area_owner.get_or_null(p_rid); - /* - if (area->get_monitor_query()) - _clear_query(area->get_monitor_query()); - */ - area->set_space(nullptr); while (area->get_shape_count()) { diff --git a/servers/physics_2d/godot_shape_2d.cpp b/servers/physics_2d/godot_shape_2d.cpp index 1e8799a727..b5dbb8a2dd 100644 --- a/servers/physics_2d/godot_shape_2d.cpp +++ b/servers/physics_2d/godot_shape_2d.cpp @@ -544,12 +544,6 @@ bool GodotConvexPolygonShape2D::intersect_segment(const Vector2 &p_begin, const bool inters = false; for (int i = 0; i < point_count; i++) { - //hmm.. no can do.. - /* - if (d.dot(points[i].normal)>=0) - continue; - */ - Vector2 res; if (!Geometry2D::segment_intersects_segment(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res)) { diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp index 5c2bda340b..04b8d3c741 100644 --- a/servers/physics_2d/godot_space_2d.cpp +++ b/servers/physics_2d/godot_space_2d.cpp @@ -888,6 +888,9 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D:: // Allowed depth can't be lower than motion length, in order to handle contacts at low speed. rcd.min_allowed_depth = MIN(motion_length, min_contact_depth); + body_aabb.position += p_parameters.motion * unsafe; + int amount = _cull_aabb_for_body(p_body, body_aabb); + int from_shape = best_shape != -1 ? best_shape : 0; int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count(); @@ -899,10 +902,6 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D:: Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j); GodotShape2D *body_shape = p_body->get_shape(j); - body_aabb.position += p_parameters.motion * unsafe; - - int amount = _cull_aabb_for_body(p_body, body_aabb); - for (int i = 0; i < amount; i++) { const GodotCollisionObject2D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { @@ -996,11 +995,8 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D:: return collided; } +// Assumes a valid collision pair, this should have been checked beforehand in the BVH or octree. void *GodotSpace2D::_broadphase_pair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_self) { - if (!A->interacts_with(B)) { - return nullptr; - } - GodotCollisionObject2D::Type type_A = A->get_type(); GodotCollisionObject2D::Type type_B = B->get_type(); if (type_A > type_B) { diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp index 928ffe0980..23c8079538 100644 --- a/servers/physics_3d/gjk_epa.cpp +++ b/servers/physics_3d/gjk_epa.cpp @@ -918,7 +918,7 @@ bool Distance( const GodotShape3D* shape0, { results.status = gjk_status==GJK::eStatus::Inside? sResults::Penetrating : - sResults::GJK_Failed ; + sResults::GJK_Failed; return(false); } } diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp index 9a6b96c411..ecdf74fd41 100644 --- a/servers/physics_3d/godot_broad_phase_3d_bvh.cpp +++ b/servers/physics_3d/godot_broad_phase_3d_bvh.cpp @@ -33,7 +33,9 @@ #include "godot_collision_object_3d.h" GodotBroadPhase3DBVH::ID GodotBroadPhase3DBVH::create(GodotCollisionObject3D *p_object, int p_subindex, const AABB &p_aabb, bool p_static) { - ID oid = bvh.create(p_object, true, p_aabb, p_subindex, !p_static, 1 << p_object->get_type(), p_static ? 0 : 0xFFFFF); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + ID oid = bvh.create(p_object, true, tree_id, tree_collision_mask, p_aabb, p_subindex); // Pair everything, don't care? return oid + 1; } @@ -42,8 +44,9 @@ void GodotBroadPhase3DBVH::move(ID p_id, const AABB &p_aabb) { } void GodotBroadPhase3DBVH::set_static(ID p_id, bool p_static) { - GodotCollisionObject3D *it = bvh.get(p_id - 1); - bvh.set_pairable(p_id - 1, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF, false); // Pair everything, don't care? + uint32_t tree_id = p_static ? TREE_STATIC : TREE_DYNAMIC; + uint32_t tree_collision_mask = p_static ? TREE_FLAG_DYNAMIC : (TREE_FLAG_STATIC | TREE_FLAG_DYNAMIC); + bvh.set_tree(p_id - 1, tree_id, tree_collision_mask, false); } void GodotBroadPhase3DBVH::remove(ID p_id) { @@ -57,7 +60,8 @@ GodotCollisionObject3D *GodotBroadPhase3DBVH::get_object(ID p_id) const { } bool GodotBroadPhase3DBVH::is_static(ID p_id) const { - return !bvh.is_pairable(p_id - 1); + uint32_t tree_id = bvh.get_tree_id(p_id - 1); + return tree_id == 0; } int GodotBroadPhase3DBVH::get_subindex(ID p_id) const { @@ -65,15 +69,15 @@ int GodotBroadPhase3DBVH::get_subindex(ID p_id) const { } int GodotBroadPhase3DBVH::cull_point(const Vector3 &p_point, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_point(p_point, p_results, p_max_results, p_result_indices); + return bvh.cull_point(p_point, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } int GodotBroadPhase3DBVH::cull_segment(const Vector3 &p_from, const Vector3 &p_to, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices); + return bvh.cull_segment(p_from, p_to, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } int GodotBroadPhase3DBVH::cull_aabb(const AABB &p_aabb, GodotCollisionObject3D **p_results, int p_max_results, int *p_result_indices) { - return bvh.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices); + return bvh.cull_aabb(p_aabb, p_results, p_max_results, nullptr, 0xFFFFFFFF, p_result_indices); } void *GodotBroadPhase3DBVH::_pair_callback(void *self, uint32_t p_A, GodotCollisionObject3D *p_object_A, int subindex_A, uint32_t p_B, GodotCollisionObject3D *p_object_B, int subindex_B) { diff --git a/servers/physics_3d/godot_broad_phase_3d_bvh.h b/servers/physics_3d/godot_broad_phase_3d_bvh.h index 7138019a9c..7660030195 100644 --- a/servers/physics_3d/godot_broad_phase_3d_bvh.h +++ b/servers/physics_3d/godot_broad_phase_3d_bvh.h @@ -36,7 +36,34 @@ #include "core/math/bvh.h" class GodotBroadPhase3DBVH : public GodotBroadPhase3D { - BVH_Manager<GodotCollisionObject3D, true, 128> bvh; + template <class T> + class UserPairTestFunction { + public: + static bool user_pair_check(const T *p_a, const T *p_b) { + // return false if no collision, decided by masks etc + return p_a->interacts_with(p_b); + } + }; + + template <class T> + class UserCullTestFunction { + public: + static bool user_cull_check(const T *p_a, const T *p_b) { + return true; + } + }; + + enum Tree { + TREE_STATIC = 0, + TREE_DYNAMIC = 1, + }; + + enum TreeFlag { + TREE_FLAG_STATIC = 1 << TREE_STATIC, + TREE_FLAG_DYNAMIC = 1 << TREE_DYNAMIC, + }; + + BVH_Manager<GodotCollisionObject3D, 2, true, 128, UserPairTestFunction<GodotCollisionObject3D>, UserCullTestFunction<GodotCollisionObject3D>> bvh; static void *_pair_callback(void *, uint32_t, GodotCollisionObject3D *, int, uint32_t, GodotCollisionObject3D *, int); static void _unpair_callback(void *, uint32_t, GodotCollisionObject3D *, int, uint32_t, GodotCollisionObject3D *, int, void *); diff --git a/servers/physics_3d/godot_collision_object_3d.h b/servers/physics_3d/godot_collision_object_3d.h index 0178838a25..515b945564 100644 --- a/servers/physics_3d/godot_collision_object_3d.h +++ b/servers/physics_3d/godot_collision_object_3d.h @@ -169,7 +169,7 @@ public: return p_other->collision_layer & collision_mask; } - _FORCE_INLINE_ bool interacts_with(GodotCollisionObject3D *p_other) const { + _FORCE_INLINE_ bool interacts_with(const GodotCollisionObject3D *p_other) const { return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask; } diff --git a/servers/physics_3d/godot_collision_solver_3d_sat.cpp b/servers/physics_3d/godot_collision_solver_3d_sat.cpp index 82e04a7e31..ca429040f5 100644 --- a/servers/physics_3d/godot_collision_solver_3d_sat.cpp +++ b/servers/physics_3d/godot_collision_solver_3d_sat.cpp @@ -345,10 +345,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_ for (int i = 0; i < clipbuf_len; i++) { real_t d = plane_B.distance_to(clipbuf_src[i]); - /* - if (d>CMP_EPSILON) - continue; - */ Vector3 closest_B = clipbuf_src[i] - plane_B.normal * d; diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index 4e1680e6ac..a1912dc660 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -1540,14 +1540,6 @@ void GodotPhysicsServer3D::free(RID p_rid) { } else if (body_owner.owns(p_rid)) { GodotBody3D *body = body_owner.get_or_null(p_rid); - /* - if (body->get_state_query()) - _clear_query(body->get_state_query()); - - if (body->get_direct_state_query()) - _clear_query(body->get_direct_state_query()); - */ - body->set_space(nullptr); while (body->get_shape_count()) { @@ -1566,11 +1558,6 @@ void GodotPhysicsServer3D::free(RID p_rid) { } else if (area_owner.owns(p_rid)) { GodotArea3D *area = area_owner.get_or_null(p_rid); - /* - if (area->get_monitor_query()) - _clear_query(area->get_monitor_query()); - */ - area->set_space(nullptr); while (area->get_shape_count()) { diff --git a/servers/physics_3d/godot_shape_3d.cpp b/servers/physics_3d/godot_shape_3d.cpp index 666e773c1c..7762c4829e 100644 --- a/servers/physics_3d/godot_shape_3d.cpp +++ b/servers/physics_3d/godot_shape_3d.cpp @@ -1284,12 +1284,6 @@ Vector3 GodotConcavePolygonShape3D::get_support(const Vector3 &p_normal) const { void GodotConcavePolygonShape3D::_cull_segment(int p_idx, _SegmentCullParams *p_params) const { const BVH *bvh = &p_params->bvh[p_idx]; - /* - if (p_params->dir.dot(bvh->aabb.get_support(-p_params->dir))>p_params->min_d) - return; //test against whole AABB, which isn't very costly - */ - - //printf("addr: %p\n",bvh); if (!bvh->aabb.intersects_segment(p_params->from, p_params->to)) { return; } diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp index ed756a7f9d..e28b6da0d9 100644 --- a/servers/physics_3d/godot_space_3d.cpp +++ b/servers/physics_3d/godot_space_3d.cpp @@ -926,6 +926,9 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D:: // Allowed depth can't be lower than motion length, in order to handle contacts at low speed. rcd.min_allowed_depth = MIN(motion_length, min_contact_depth); + body_aabb.position += p_parameters.motion * unsafe; + int amount = _cull_aabb_for_body(p_body, body_aabb); + int from_shape = best_shape != -1 ? best_shape : 0; int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count(); @@ -937,10 +940,6 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D:: Transform3D body_shape_xform = ugt * p_body->get_shape_transform(j); GodotShape3D *body_shape = p_body->get_shape(j); - body_aabb.position += p_parameters.motion * unsafe; - - int amount = _cull_aabb_for_body(p_body, body_aabb); - for (int i = 0; i < amount; i++) { const GodotCollisionObject3D *col_obj = intersection_query_results[i]; if (p_parameters.exclude_bodies.has(col_obj->get_self())) { @@ -1008,11 +1007,8 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D:: return collided; } +// Assumes a valid collision pair, this should have been checked beforehand in the BVH or octree. void *GodotSpace3D::_broadphase_pair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_self) { - if (!A->interacts_with(B)) { - return nullptr; - } - GodotCollisionObject3D::Type type_A = A->get_type(); GodotCollisionObject3D::Type type_B = B->get_type(); if (type_A > type_B) { diff --git a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp index a7a7843499..1c4d5dec23 100644 --- a/servers/physics_3d/joints/godot_hinge_joint_3d.cpp +++ b/servers/physics_3d/joints/godot_hinge_joint_3d.cpp @@ -213,16 +213,12 @@ bool GodotHingeJoint3D::setup(real_t p_step) { m_solveLimit = false; m_accLimitImpulse = real_t(0.); - //if (m_lowerLimit < m_upperLimit) if (m_useLimit && m_lowerLimit <= m_upperLimit) { - //if (hingeAngle <= m_lowerLimit*m_limitSoftness) if (hingeAngle <= m_lowerLimit) { m_correction = (m_lowerLimit - hingeAngle); m_limitSign = 1.0f; m_solveLimit = true; - } - //else if (hingeAngle >= m_upperLimit*m_limitSoftness) - else if (hingeAngle >= m_upperLimit) { + } else if (hingeAngle >= m_upperLimit) { m_correction = m_upperLimit - hingeAngle; m_limitSign = -1.0f; m_solveLimit = true; diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index d8f2a2a780..45816e3244 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -336,6 +336,8 @@ Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Ref<PhysicsRayQueryPa } Array PhysicsDirectSpaceState2D::_intersect_point(const Ref<PhysicsPointQueryParameters2D> &p_point_query, int p_max_results) { + ERR_FAIL_COND_V(p_point_query.is_null(), Array()); + Vector<ShapeResult> ret; ret.resize(p_max_results); diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index 8fafd07f87..fc119e49e9 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -339,6 +339,8 @@ Dictionary PhysicsDirectSpaceState3D::_intersect_ray(const Ref<PhysicsRayQueryPa } Array PhysicsDirectSpaceState3D::_intersect_point(const Ref<PhysicsPointQueryParameters3D> &p_point_query, int p_max_results) { + ERR_FAIL_COND_V(p_point_query.is_null(), Array()); + Vector<ShapeResult> ret; ret.resize(p_max_results); diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index f405dea770..6848620b48 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -110,7 +110,7 @@ void preregister_server_types() { shader_types = memnew(ShaderTypes); GDREGISTER_CLASS(TextServerManager); - GDREGISTER_VIRTUAL_CLASS(TextServer); + GDREGISTER_ABSTRACT_CLASS(TextServer); GDREGISTER_CLASS(TextServerExtension); Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager")); @@ -119,20 +119,20 @@ void preregister_server_types() { void register_server_types() { OS::get_singleton()->set_has_server_feature_callback(has_server_feature_callback); - GDREGISTER_VIRTUAL_CLASS(DisplayServer); - GDREGISTER_VIRTUAL_CLASS(RenderingServer); + GDREGISTER_ABSTRACT_CLASS(DisplayServer); + GDREGISTER_ABSTRACT_CLASS(RenderingServer); GDREGISTER_CLASS(AudioServer); - GDREGISTER_VIRTUAL_CLASS(PhysicsServer2D); - GDREGISTER_VIRTUAL_CLASS(PhysicsServer3D); - GDREGISTER_VIRTUAL_CLASS(NavigationServer2D); - GDREGISTER_VIRTUAL_CLASS(NavigationServer3D); + GDREGISTER_ABSTRACT_CLASS(PhysicsServer2D); + GDREGISTER_ABSTRACT_CLASS(PhysicsServer3D); + GDREGISTER_ABSTRACT_CLASS(NavigationServer2D); + GDREGISTER_ABSTRACT_CLASS(NavigationServer3D); GDREGISTER_CLASS(XRServer); GDREGISTER_CLASS(CameraServer); - GDREGISTER_VIRTUAL_CLASS(RenderingDevice); + GDREGISTER_ABSTRACT_CLASS(RenderingDevice); - GDREGISTER_VIRTUAL_CLASS(XRInterface); + GDREGISTER_ABSTRACT_CLASS(XRInterface); GDREGISTER_CLASS(XRInterfaceExtension); // can't register this as virtual because we need a creation function for our extensions. GDREGISTER_CLASS(XRPose); GDREGISTER_CLASS(XRPositionalTracker); @@ -149,7 +149,7 @@ void register_server_types() { GDREGISTER_CLASS(AudioBusLayout); GDREGISTER_CLASS(AudioStreamGenerator); - GDREGISTER_VIRTUAL_CLASS(AudioStreamGeneratorPlayback); + GDREGISTER_ABSTRACT_CLASS(AudioStreamGeneratorPlayback); { //audio effects @@ -183,12 +183,12 @@ void register_server_types() { GDREGISTER_CLASS(AudioEffectRecord); GDREGISTER_CLASS(AudioEffectSpectrumAnalyzer); - GDREGISTER_VIRTUAL_CLASS(AudioEffectSpectrumAnalyzerInstance); + GDREGISTER_ABSTRACT_CLASS(AudioEffectSpectrumAnalyzerInstance); GDREGISTER_CLASS(AudioEffectCapture); } - GDREGISTER_VIRTUAL_CLASS(RenderingDevice); + GDREGISTER_ABSTRACT_CLASS(RenderingDevice); GDREGISTER_CLASS(RDTextureFormat); GDREGISTER_CLASS(RDTextureView); GDREGISTER_CLASS(RDAttachmentFormat); @@ -208,16 +208,16 @@ void register_server_types() { GDREGISTER_CLASS(CameraFeed); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState2D); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState2D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectBodyState2D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectSpaceState2D); GDREGISTER_CLASS(PhysicsRayQueryParameters2D); GDREGISTER_CLASS(PhysicsPointQueryParameters2D); GDREGISTER_CLASS(PhysicsShapeQueryParameters2D); GDREGISTER_CLASS(PhysicsTestMotionParameters2D); GDREGISTER_CLASS(PhysicsTestMotionResult2D); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectBodyState3D); - GDREGISTER_VIRTUAL_CLASS(PhysicsDirectSpaceState3D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectBodyState3D); + GDREGISTER_ABSTRACT_CLASS(PhysicsDirectSpaceState3D); GDREGISTER_CLASS(PhysicsRayQueryParameters3D); GDREGISTER_CLASS(PhysicsPointQueryParameters3D); GDREGISTER_CLASS(PhysicsShapeQueryParameters3D); diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h index 7032f3fb03..8f82356d11 100644 --- a/servers/rendering/rasterizer_dummy.h +++ b/servers/rendering/rasterizer_dummy.h @@ -31,7 +31,6 @@ #ifndef RASTERIZER_DUMMY_H #define RASTERIZER_DUMMY_H -#include "core/math/camera_matrix.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" #include "scene/resources/mesh.h" @@ -72,11 +71,11 @@ public: /* SHADOW ATLAS API */ RID shadow_atlas_create() override { return RID(); } - void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) override {} + void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override {} void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {} bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; } - void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) override {} + void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override {} int get_directional_light_shadow_size(RID p_light_intance) override { return 0; } void set_directional_shadow_count(int p_count) override {} @@ -409,10 +408,10 @@ public: void light_set_color(RID p_light, const Color &p_color) override {} void light_set_param(RID p_light, RS::LightParam p_param, float p_value) override {} void light_set_shadow(RID p_light, bool p_enabled) override {} - void light_set_shadow_color(RID p_light, const Color &p_color) override {} void light_set_projector(RID p_light, RID p_texture) override {} void light_set_negative(RID p_light, bool p_enable) override {} void light_set_cull_mask(RID p_light, uint32_t p_mask) override {} + void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) override {} void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) override {} void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) override {} void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) override {} @@ -561,6 +560,7 @@ public: void particles_set_speed_scale(RID p_particles, double p_scale) override {} void particles_set_use_local_coordinates(RID p_particles, bool p_enable) override {} void particles_set_process_material(RID p_particles, RID p_material) override {} + RID particles_get_process_material(RID p_particles) const override { return RID(); } void particles_set_fixed_fps(RID p_particles, int p_fps) override {} void particles_set_interpolate(RID p_particles, bool p_enable) override {} void particles_set_fractional_delta(RID p_particles, bool p_enable) override {} diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 418d2bc42e..a96f873088 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -66,7 +66,7 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas } } - RENDER_TIMESTAMP("Render Canvas Items"); + RENDER_TIMESTAMP("Render CanvasItems"); bool sdf_flag; RSG::canvas_render->canvas_render_items(p_to_render_target, list, p_modulate, p_lights, p_directional_lights, p_transform, p_default_filter, p_default_repeat, p_snap_2d_vertices_to_pixel, sdf_flag); @@ -338,7 +338,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2 } void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, const Rect2 &p_clip_rect, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_transforms_to_pixel, bool p_snap_2d_vertices_to_pixel) { - RENDER_TIMESTAMP(">Render Canvas"); + RENDER_TIMESTAMP("> Render Canvas"); sdf_used = false; snapping_2d_transforms_to_pixel = p_snap_2d_transforms_to_pixel; @@ -384,7 +384,7 @@ void RendererCanvasCull::render_canvas(RID p_render_target, Canvas *p_canvas, co } } - RENDER_TIMESTAMP("<End Render Canvas"); + RENDER_TIMESTAMP("< Render Canvas"); } bool RendererCanvasCull::was_sdf_used() { diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp index 82e8bd6ef9..fa4d9c8b31 100644 --- a/servers/rendering/renderer_compositor.cpp +++ b/servers/rendering/renderer_compositor.cpp @@ -45,7 +45,7 @@ bool RendererCompositor::is_xr_enabled() const { } RendererCompositor::RendererCompositor() { - xr_enabled = GLOBAL_GET("rendering/xr/enabled"); + xr_enabled = GLOBAL_GET("xr/shaders/enabled"); } RendererCanvasRender *RendererCanvasRender::singleton = nullptr; diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index f245af9a4a..e58fd7bebc 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -31,13 +31,11 @@ #ifndef RENDERING_SERVER_COMPOSITOR_H #define RENDERING_SERVER_COMPOSITOR_H -#include "core/math/camera_matrix.h" -#include "core/templates/pair.h" -#include "core/templates/self_list.h" #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_storage.h" #include "servers/rendering_server.h" + class RendererSceneRender; struct BlitToScreen { RID render_target; diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index 6ad3556969..24108b3a59 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -287,21 +287,21 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 1; - u.ids.push_back(state_uniform); + u.append_id(state_uniform); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(element_buffer); + u.append_id(element_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - u.ids.push_back(cluster_render_buffer); + u.append_id(cluster_render_buffer); uniforms.push_back(u); } @@ -314,14 +314,14 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(cluster_render_buffer); + u.append_id(cluster_render_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(cluster_buffer); + u.append_id(cluster_buffer); uniforms.push_back(u); } @@ -329,7 +329,7 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - u.ids.push_back(element_buffer); + u.append_id(element_buffer); uniforms.push_back(u); } @@ -342,14 +342,14 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(cluster_buffer); + u.append_id(cluster_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(p_color_buffer); + u.append_id(p_color_buffer); uniforms.push_back(u); } @@ -357,14 +357,14 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; - u.ids.push_back(p_depth_buffer); + u.append_id(p_depth_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 4; - u.ids.push_back(p_depth_buffer_sampler); + u.append_id(p_depth_buffer_sampler); uniforms.push_back(u); } @@ -398,7 +398,7 @@ void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMa } void ClusterBuilderRD::bake_cluster() { - RENDER_TIMESTAMP(">Bake Cluster"); + RENDER_TIMESTAMP("> Bake 3D Cluster"); RD::get_singleton()->draw_command_begin_label("Bake Light Cluster"); @@ -429,7 +429,7 @@ void ClusterBuilderRD::bake_cluster() { RD::get_singleton()->buffer_update(element_buffer, 0, sizeof(RenderElementData) * render_element_count, render_elements, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); - RENDER_TIMESTAMP("Render Elements"); + RENDER_TIMESTAMP("Render 3D Cluster Elements"); //render elements { @@ -466,7 +466,7 @@ void ClusterBuilderRD::bake_cluster() { RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_COMPUTE); } //store elements - RENDER_TIMESTAMP("Pack Elements"); + RENDER_TIMESTAMP("Pack 3D Cluster Elements"); { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -492,7 +492,7 @@ void ClusterBuilderRD::bake_cluster() { } else { RD::get_singleton()->barrier(RD::BARRIER_MASK_TRANSFER, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE); } - RENDER_TIMESTAMP("<Bake Cluster"); + RENDER_TIMESTAMP("< Bake 3D Cluster"); RD::get_singleton()->draw_command_end_label(); } diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 02a0b6f184..a5a9dae0b9 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -60,7 +60,7 @@ RID EffectsRD::_get_uniform_set_from_image(RID p_image) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_image); + u.append_id(p_image); uniforms.push_back(u); //any thing with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 1); @@ -82,7 +82,7 @@ RID EffectsRD::_get_uniform_set_for_input(RID p_texture) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_INPUT_ATTACHMENT; u.binding = 0; - u.ids.push_back(p_texture); + u.append_id(p_texture); uniforms.push_back(u); // This is specific to our subpass shader RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, TONEMAP_MODE_SUBPASS), 0); @@ -104,8 +104,8 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture); uniforms.push_back(u); // anything with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, tonemap.shader.version_get_shader(tonemap.shader_version, 0), 0); @@ -132,16 +132,16 @@ RID EffectsRD::_get_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2 RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture1); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture1); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture2); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture2); uniforms.push_back(u); } // anything with the same configuration (one texture in binding 0 for set 0), is good @@ -164,8 +164,8 @@ RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_m RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture); uniforms.push_back(u); //any thing with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, luminance_reduce.shader.version_get_shader(luminance_reduce.shader_version, 0), 0); @@ -191,8 +191,8 @@ RID EffectsRD::_get_compute_uniform_set_from_texture_and_sampler(RID p_texture, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_sampler); - u.ids.push_back(p_texture); + u.append_id(p_sampler); + u.append_id(p_texture); uniforms.push_back(u); //any thing with the same configuration (one texture in binding 0 for set 0), is good RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.blur_shader.version_get_shader(ssao.blur_shader_version, 0), 0); @@ -219,16 +219,16 @@ RID EffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture1); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture1); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; - u.ids.push_back(p_use_mipmaps ? default_mipmap_sampler : default_sampler); - u.ids.push_back(p_texture2); + u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler); + u.append_id(p_texture2); uniforms.push_back(u); } //any thing with the same configuration (one texture in binding 0 for set 0), is good @@ -256,14 +256,14 @@ RID EffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_te RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_texture1); + u.append_id(p_texture1); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(p_texture2); + u.append_id(p_texture2); uniforms.push_back(u); } //any thing with the same configuration (one texture in binding 0 for set 0), is good @@ -332,7 +332,7 @@ void EffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer RD::get_singleton()->draw_list_draw(draw_list, true); } -void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary) { +void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview) { memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); if (p_flip_y) { @@ -348,10 +348,18 @@ void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, copy_to_fb.push_constant.srgb = true; } + CopyToFBMode mode; + if (p_multiview) { + mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW; + } else { + mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY; + } + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); if (p_secondary.is_valid()) { + // TODO may need to do this differently when reading from depth buffer for multiview RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_secondary), 1); } RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); @@ -638,13 +646,13 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R ssr.push_constant.metallic_mask[3] = CLAMP(p_metallic_mask.a * 255.0, 0, 255); store_camera(p_camera, ssr.push_constant.projection); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssr.pipelines[(p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) ? SCREEN_SPACE_REFLECTION_ROUGH : SCREEN_SPACE_REFLECTION_NORMAL]); RD::get_singleton()->compute_list_set_push_constant(compute_list, &ssr.push_constant, sizeof(ScreenSpaceReflectionPushConstant)); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output_blur, p_scale_depth), 0); - if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { + if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_output, p_blur_radius), 1); } else { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_output), 1); @@ -655,7 +663,7 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.width, p_screen_size.height, 1); } - if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) { + if (p_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED) { //blur RD::get_singleton()->compute_list_add_barrier(compute_list); @@ -667,10 +675,10 @@ void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, R ssr_filter.push_constant.proj_info[2] = (1.0f - p_camera.matrix[0][2]) / p_camera.matrix[0][0]; ssr_filter.push_constant.proj_info[3] = (1.0f + p_camera.matrix[1][2]) / p_camera.matrix[1][1]; ssr_filter.push_constant.vertical = 0; - if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_LOW) { + if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_LOW) { ssr_filter.push_constant.steps = p_max_steps / 3; ssr_filter.push_constant.increment = 3; - } else if (p_roughness_quality == RS::ENV_SSR_ROUGNESS_QUALITY_MEDIUM) { + } else if (p_roughness_quality == RS::ENV_SSR_ROUGHNESS_QUALITY_MEDIUM) { ssr_filter.push_constant.steps = p_max_steps / 2; ssr_filter.push_constant.increment = 2; } else { @@ -1381,28 +1389,28 @@ void EffectsRD::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_depth_mipmaps[depth_index + 1]); + u.append_id(p_depth_mipmaps[depth_index + 1]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(p_depth_mipmaps[depth_index + 2]); + u.append_id(p_depth_mipmaps[depth_index + 2]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(p_depth_mipmaps[depth_index + 3]); + u.append_id(p_depth_mipmaps[depth_index + 3]); uniforms.push_back(u); } if (use_full_mips) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(p_depth_mipmaps[4]); + u.append_id(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); @@ -1529,22 +1537,22 @@ void EffectsRD::generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, 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); + u.append_id(default_sampler); + u.append_id(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); + u.append_id(p_normal_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(ss_effects.gather_constants_buffer); + u.append_id(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); @@ -1556,22 +1564,22 @@ void EffectsRD::generate_ssao(RID p_normal_buffer, RID p_depth_mipmaps_texture, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_ao_pong); + u.append_id(p_ao_pong); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 1; - u.ids.push_back(default_sampler); - u.ids.push_back(p_importance_map); + u.append_id(default_sampler); + u.append_id(p_importance_map); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(ssao.importance_map_load_counter); + u.append_id(ssao.importance_map_load_counter); uniforms.push_back(u); } r_importance_map_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, ssao.gather_shader.version_get_shader(ssao.gather_shader_version, 2), 1); @@ -1803,15 +1811,15 @@ void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, 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); + u.append_id(default_mipmap_sampler); + u.append_id(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); + u.append_id(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); @@ -1823,22 +1831,22 @@ void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, 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); + u.append_id(default_sampler); + u.append_id(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); + u.append_id(p_normal_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(ss_effects.gather_constants_buffer); + u.append_id(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); @@ -1850,22 +1858,22 @@ void EffectsRD::screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 0; - u.ids.push_back(p_ssil_pong); + u.append_id(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); + u.append_id(default_sampler); + u.append_id(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); + u.append_id(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); @@ -2032,7 +2040,7 @@ void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, u memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id; - roughness.push_constant.roughness = p_roughness; + roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. roughness.push_constant.sample_count = p_sample_count; roughness.push_constant.use_direct_write = p_roughness == 0.0; roughness.push_constant.face_size = p_size; @@ -2040,7 +2048,7 @@ void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, u RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipeline); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture, true), 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1); RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant)); @@ -2060,7 +2068,7 @@ void EffectsRD::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_fra memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant)); roughness.push_constant.face_id = p_face_id; - roughness.push_constant.roughness = p_roughness; + roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in. roughness.push_constant.sample_count = p_sample_count; roughness.push_constant.use_direct_write = p_roughness == 0.0; roughness.push_constant.face_size = p_size; @@ -2123,7 +2131,7 @@ void EffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = i; - u.ids.push_back(p_dest_cubemap[i]); + u.append_id(p_dest_cubemap[i]); uniforms.push_back(u); } if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) { @@ -2367,15 +2375,26 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { copy_modes.push_back("\n"); copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); + copy_modes.push_back("\n#define MULTIVIEW\n"); + copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); copy_to_fb.shader.initialize(copy_modes); + if (!RendererCompositorRD::singleton->is_xr_enabled()) { + copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW, false); + copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW_WITH_DEPTH, false); + } + copy_to_fb.shader_version = copy_to_fb.shader.version_create(); //use additive for (int i = 0; i < COPY_TO_FB_MAX; i++) { - copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + if (copy_to_fb.shader.is_variant_enabled(i)) { + copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } else { + copy_to_fb.pipelines[i].clear(); + } } } @@ -2632,7 +2651,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(ssao.importance_map_load_counter); + u.append_id(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); @@ -2747,7 +2766,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(filter.coefficient_buffer); + u.append_id(filter.coefficient_buffer); uniforms.push_back(u); } filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); @@ -2765,7 +2784,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(filter.coefficient_buffer); + u.append_id(filter.coefficient_buffer); uniforms.push_back(u); } filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1); @@ -2902,7 +2921,7 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(ssil.importance_map_load_counter); + u.append_id(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); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index f5e5b1ace7..eca5e09800 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -203,6 +203,9 @@ private: COPY_TO_FB_COPY, COPY_TO_FB_COPY_PANORAMA_TO_DP, COPY_TO_FB_COPY2, + + COPY_TO_FB_MULTIVIEW, + COPY_TO_FB_MULTIVIEW_WITH_DEPTH, COPY_TO_FB_MAX, }; @@ -893,7 +896,7 @@ public: bool get_prefer_raster_effects(); void fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness); - void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID()); + void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false); void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false); void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); 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 87301a9d3a..6b500260ef 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -30,6 +30,7 @@ #include "render_forward_clustered.h" #include "core/config/project_settings.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" #include "servers/rendering/rendering_device.h" #include "servers/rendering/rendering_server_default.h" @@ -824,7 +825,6 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat if (p_index >= (int)scene_state.uniform_buffers.size()) { uint32_t from = scene_state.uniform_buffers.size(); scene_state.uniform_buffers.resize(p_index + 1); - render_pass_uniform_sets.resize(p_index + 1); for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) { scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO)); } @@ -969,10 +969,11 @@ void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, con if (inst->fade_near || inst->fade_far) { float fade_dist = inst->transform.origin.distance_to(p_render_data->cam_transform.origin); + // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player. if (inst->fade_far && fade_dist > inst->fade_far_begin) { - fade_alpha = MAX(0.0, 1.0 - (fade_dist - inst->fade_far_begin) / (inst->fade_far_end - inst->fade_far_begin)); + fade_alpha = Math::smoothstep(0.0f, 1.0f, 1.0f - (fade_dist - inst->fade_far_begin) / (inst->fade_far_end - inst->fade_far_begin)); } else if (inst->fade_near && fade_dist < inst->fade_near_end) { - fade_alpha = MAX(0.0, (fade_dist - inst->fade_near_begin) / (inst->fade_near_end - inst->fade_near_begin)); + fade_alpha = Math::smoothstep(0.0f, 1.0f, (fade_dist - inst->fade_near_begin) / (inst->fade_near_end - inst->fade_near_begin)); } } @@ -1390,7 +1391,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); RID sky_rid = env->sky; if (sky_rid.is_valid()) { @@ -1416,7 +1417,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool needs_pre_resolve = _needs_post_prepass_render(p_render_data, using_sdfgi || using_voxelgi); if (needs_pre_resolve) { - RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (parallel)"); + RENDER_TIMESTAMP("GI + Render Depth Pre-Pass (Parallel)"); } else { RENDER_TIMESTAMP("Render Depth Pre-Pass"); } @@ -1443,8 +1444,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co } if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { - RENDER_TIMESTAMP("Resolve Depth Pre-Pass"); - RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass"); + RENDER_TIMESTAMP("Resolve Depth Pre-Pass (MSAA)"); + RD::get_singleton()->draw_command_begin_label("Resolve Depth Pre-Pass (MSAA)"); if (depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS || depth_pass_mode == PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI) { if (needs_pre_resolve) { RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); @@ -1561,15 +1562,15 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (using_separate_specular) { if (using_sss) { - RENDER_TIMESTAMP("Sub Surface Scattering"); - RD::get_singleton()->draw_command_begin_label("Process Sub Surface Scattering"); + RENDER_TIMESTAMP("Sub-Surface Scattering"); + RD::get_singleton()->draw_command_begin_label("Process Sub-Surface Scattering"); _process_sss(p_render_data->render_buffers, p_render_data->cam_projection); RD::get_singleton()->draw_command_end_label(); } if (using_ssr) { - RENDER_TIMESTAMP("Screen Space Reflection"); - RD::get_singleton()->draw_command_begin_label("Process Screen Space Reflections"); + RENDER_TIMESTAMP("Screen-Space Reflections"); + RD::get_singleton()->draw_command_begin_label("Process Screen-Space Reflections"); _process_ssr(p_render_data->render_buffers, render_buffer->color_fb, render_buffer->normal_roughness_buffer, render_buffer->specular, render_buffer->specular, Color(0, 0, 0, 1), p_render_data->environment, p_render_data->cam_projection, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED); RD::get_singleton()->draw_command_end_label(); } else { @@ -1589,9 +1590,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co _render_buffers_copy_depth_texture(p_render_data); } - RENDER_TIMESTAMP("Render Transparent Pass"); + RENDER_TIMESTAMP("Render 3D Transparent Pass"); - RD::get_singleton()->draw_command_begin_label("Render Transparent Pass"); + RD::get_singleton()->draw_command_begin_label("Render 3D Transparent Pass"); rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_ALPHA, p_render_data, radiance_texture, true); @@ -1617,7 +1618,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Copy framebuffer for SSIL"); if (using_ssil) { - RENDER_TIMESTAMP("Copy Final Framebuffer"); + RENDER_TIMESTAMP("Copy Final Framebuffer (SSIL)"); _copy_framebuffer_to_ssil(p_render_data->render_buffers); } RD::get_singleton()->draw_command_end_label(); @@ -1730,7 +1731,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { } void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { - RENDER_TIMESTAMP("Setup Render Collider Heightfield"); + RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1768,9 +1769,9 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con } void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { - RENDER_TIMESTAMP("Setup Rendering Material"); + RENDER_TIMESTAMP("Setup Rendering 3D Material"); - RD::get_singleton()->draw_command_begin_label("Render Material"); + RD::get_singleton()->draw_command_begin_label("Render 3D Material"); RenderDataRD render_data; render_data.cam_projection = p_cam_projection; @@ -1794,7 +1795,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set); @@ -1840,7 +1841,7 @@ void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, true, false, rp_uniform_set, true); @@ -1990,11 +1991,9 @@ void RenderForwardClustered::_update_render_base_uniform_set() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -2007,6 +2006,9 @@ void RenderForwardClustered::_update_render_base_uniform_set() { ids_ptr[9] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_custom(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); + uniforms.push_back(u); } @@ -2014,7 +2016,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(scene_shader.shadow_sampler); + u.append_id(scene_shader.shadow_sampler); uniforms.push_back(u); } @@ -2041,7 +2043,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -2068,7 +2070,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -2076,14 +2078,14 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_omni_light_buffer()); + u.append_id(get_omni_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_spot_light_buffer()); + u.append_id(get_spot_light_buffer()); uniforms.push_back(u); } @@ -2091,28 +2093,28 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_reflection_probe_buffer()); + u.append_id(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(get_directional_light_buffer()); + u.append_id(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_buffer); + u.append_id(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_capture_buffer); + u.append_id(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { @@ -2120,7 +2122,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { @@ -2128,14 +2130,14 @@ void RenderForwardClustered::_update_render_base_uniform_set() { u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { RD::Uniform u; u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_decal_buffer()); + u.append_id(get_decal_buffer()); uniforms.push_back(u); } @@ -2143,7 +2145,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2151,7 +2153,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 15; - u.ids.push_back(sdfgi_get_ubo()); + u.append_id(sdfgi_get_ubo()); uniforms.push_back(u); } @@ -2160,9 +2162,6 @@ void RenderForwardClustered::_update_render_base_uniform_set() { } RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) { - //there should always be enough uniform buffers for render passes, otherwise bugs - ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID()); - RenderBufferDataForwardClustered *rb = nullptr; if (p_render_data && p_render_data->render_buffers.is_valid()) { rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); @@ -2176,7 +2175,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffers[p_index]); + u.append_id(scene_state.uniform_buffers[p_index]); uniforms.push_back(u); } { @@ -2187,7 +2186,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (instance_buffer == RID()) { instance_buffer = scene_shader.default_vec4_xform_buffer; // any buffer will do since its not used } - u.ids.push_back(instance_buffer); + u.append_id(instance_buffer); uniforms.push_back(u); } { @@ -2200,7 +2199,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(radiance_texture); + u.append_id(radiance_texture); uniforms.push_back(u); } @@ -2210,9 +2209,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { - u.ids.push_back(ref_texture); + u.append_id(ref_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); } uniforms.push_back(u); } @@ -2228,7 +2227,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (!texture.is_valid()) { texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); } - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { @@ -2236,9 +2235,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { - u.ids.push_back(directional_shadow_get_texture()); + u.append_id(directional_shadow_get_texture()); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); } uniforms.push_back(u); } @@ -2246,16 +2245,16 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(scene_state.max_lightmaps); + RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { if (p_render_data && i < p_render_data->lightmaps->size()) { RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); RID texture = storage->lightmap_get_texture(base); RID rd_texture = storage->texture_get_rd_texture(texture); - u.ids.write[i] = rd_texture; + u.append_id(rd_texture); } else { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } } @@ -2265,7 +2264,6 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(MAX_VOXEL_GI_INSTANCESS); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { if (p_render_data && i < (int)p_render_data->voxel_gi_instances->size()) { @@ -2273,9 +2271,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend if (!tex.is_valid()) { tex = default_tex; } - u.ids.write[i] = tex; + u.append_id(tex); } else { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } } @@ -2287,7 +2285,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = (p_render_data && p_render_data->cluster_buffer.is_valid()) ? p_render_data->cluster_buffer : scene_shader.default_vec4_xform_buffer; - u.ids.push_back(cb); + u.append_id(cb); uniforms.push_back(u); } @@ -2297,7 +2295,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID(); RID texture = (dbt.is_valid()) ? dbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { @@ -2306,7 +2304,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } @@ -2316,7 +2314,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } @@ -2326,7 +2324,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID aot = rb ? render_buffers_get_ao_texture(p_render_data->render_buffers) : RID(); RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } @@ -2336,7 +2334,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID ambient_buffer = rb ? render_buffers_get_gi_ambient_texture(p_render_data->render_buffers) : RID(); RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } @@ -2346,7 +2344,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID reflection_buffer = rb ? render_buffers_get_gi_reflection_texture(p_render_data->render_buffers) : RID(); RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { @@ -2359,7 +2357,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } else { t = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); } - u.ids.push_back(t); + u.append_id(t); uniforms.push_back(u); } { @@ -2367,9 +2365,9 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend u.binding = 16; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (rb && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) { - u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_data->render_buffers)); + u.append_id(render_buffers_get_sdfgi_occlusion_texture(p_render_data->render_buffers)); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } @@ -2377,7 +2375,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend RD::Uniform u; u.binding = 17; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(rb ? render_buffers_get_voxel_gi_buffer(p_render_data->render_buffers) : render_buffers_get_default_voxel_gi_buffer()); + u.append_id(rb ? render_buffers_get_voxel_gi_buffer(p_render_data->render_buffers) : render_buffers_get_default_voxel_gi_buffer()); uniforms.push_back(u); } { @@ -2393,7 +2391,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend } else { vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); } - u.ids.push_back(vfog); + u.append_id(vfog); uniforms.push_back(u); } { @@ -2402,42 +2400,29 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend 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); + u.append_id(texture); uniforms.push_back(u); } } - if (p_index >= (int)render_pass_uniform_sets.size()) { - render_pass_uniform_sets.resize(p_index + 1); - } - - if (render_pass_uniform_sets[p_index].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[p_index])) { - RD::get_singleton()->free(render_pass_uniform_sets[p_index]); - } - - render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET); - return render_pass_uniform_sets[p_index]; + return UniformSetCacheRD::get_singleton()->get_cache_vec(scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET, uniforms); } RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) { - if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) { - RD::get_singleton()->free(sdfgi_pass_uniform_set); - } - Vector<RD::Uniform> uniforms; { RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffers[0]); + u.append_id(scene_state.uniform_buffers[0]); uniforms.push_back(u); } { RD::Uniform u; u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.instance_buffer[RENDER_LIST_SECONDARY]); + u.append_id(scene_state.instance_buffer[RENDER_LIST_SECONDARY]); uniforms.push_back(u); } { @@ -2446,7 +2431,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(radiance_texture); + u.append_id(radiance_texture); uniforms.push_back(u); } @@ -2456,7 +2441,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(ref_texture); + u.append_id(ref_texture); uniforms.push_back(u); } @@ -2466,7 +2451,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } @@ -2476,7 +2461,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } @@ -2485,10 +2470,10 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(scene_state.max_lightmaps); + RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } uniforms.push_back(u); @@ -2499,10 +2484,10 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(MAX_VOXEL_GI_INSTANCESS); + RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); for (int i = 0; i < MAX_VOXEL_GI_INSTANCESS; i++) { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } uniforms.push_back(u); @@ -2513,7 +2498,7 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = scene_shader.default_vec4_xform_buffer; - u.ids.push_back(cb); + u.append_id(cb); uniforms.push_back(u); } @@ -2523,33 +2508,32 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(p_albedo_texture); + u.append_id(p_albedo_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; - u.ids.push_back(p_emission_texture); + u.append_id(p_emission_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(p_emission_aniso_texture); + u.append_id(p_emission_aniso_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; - u.ids.push_back(p_geom_facing_texture); + u.append_id(p_geom_facing_texture); uniforms.push_back(u); } - sdfgi_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_sdfgi_rd, RENDER_PASS_UNIFORM_SET); - return sdfgi_pass_uniform_set; + return UniformSetCacheRD::get_singleton()->get_cache_vec(scene_shader.default_shader_sdfgi_rd, RENDER_PASS_UNIFORM_SET, uniforms); } RID RenderForwardClustered::_render_buffers_get_normal_texture(RID p_render_buffers) { @@ -3217,17 +3201,6 @@ RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) : RenderForwardClustered::~RenderForwardClustered() { directional_shadow_atlas_set_size(0); - //clear base uniform set if still valid - for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) { - if (render_pass_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_sets[i])) { - RD::get_singleton()->free(render_pass_uniform_sets[i]); - } - } - - if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) { - RD::get_singleton()->free(sdfgi_pass_uniform_set); - } - { for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) { RD::get_singleton()->free(scene_state.uniform_buffers[i]); 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 f858887bd0..dd5c719352 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -121,8 +121,6 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb); RID render_base_uniform_set; - LocalVector<RID> render_pass_uniform_sets; - RID sdfgi_pass_uniform_set; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; 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 7987a98b0e..b4def4e11c 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 @@ -557,7 +557,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.renames["RIM"] = "rim"; actions.renames["RIM_TINT"] = "rim_tint"; actions.renames["CLEARCOAT"] = "clearcoat"; - actions.renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; + actions.renames["CLEARCOAT_ROUGHNESS"] = "clearcoat_roughness"; actions.renames["ANISOTROPY"] = "anisotropy"; actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; actions.renames["SSS_STRENGTH"] = "sss_strength"; @@ -607,7 +607,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n"; actions.usage_defines["RIM_TINT"] = "@RIM"; actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n"; - actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; + actions.usage_defines["CLEARCOAT_ROUGHNESS"] = "@CLEARCOAT"; actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n"; actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; actions.usage_defines["AO"] = "#define AO_USED\n"; @@ -663,20 +663,12 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n"; - bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); - - if (!force_blinn) { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - } else { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; - } + actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; actions.custom_samplers["SCREEN_TEXTURE"] = "material_samplers[3]"; // linear filter with mipmaps actions.custom_samplers["DEPTH_TEXTURE"] = "material_samplers[3]"; actions.custom_samplers["NORMAL_ROUGHNESS_TEXTURE"] = "material_samplers[1]"; // linear filter - actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; - actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; @@ -759,7 +751,7 @@ void fragment() { Vector<RD::Uniform> uniforms; RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(default_vec4_xform_buffer); + u.append_id(default_vec4_xform_buffer); u.binding = 0; uniforms.push_back(u); 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 778d7baa5d..957b490664 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -306,7 +306,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(scene_state.uniform_buffers[p_index]); + u.append_id(scene_state.uniform_buffers[p_index]); uniforms.push_back(u); } @@ -320,7 +320,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(radiance_texture); + u.append_id(radiance_texture); uniforms.push_back(u); } @@ -330,9 +330,9 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (ref_texture.is_valid()) { - u.ids.push_back(ref_texture); + u.append_id(ref_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK)); } uniforms.push_back(u); } @@ -348,7 +348,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ if (!texture.is_valid()) { texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); } - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { @@ -356,9 +356,9 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { - u.ids.push_back(directional_shadow_get_texture()); + u.append_id(directional_shadow_get_texture()); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); } uniforms.push_back(u); } @@ -368,16 +368,16 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.resize(scene_state.max_lightmaps); + RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { if (p_render_data && i < p_render_data->lightmaps->size()) { RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]); RID texture = storage->lightmap_get_texture(base); RID rd_texture = storage->texture_get_rd_texture(texture); - u.ids.write[i] = rd_texture; + u.append_id(rd_texture); } else { - u.ids.write[i] = default_tex; + u.append_id(default_tex); } } @@ -411,7 +411,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer; - u.ids.push_back(cb); + u.append_id(cb); uniforms.push_back(u); } */ @@ -422,7 +422,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID dbt = rb ? render_buffers_get_back_depth_texture(p_render_data->render_buffers) : RID(); RID texture = (dbt.is_valid()) ? dbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { @@ -431,7 +431,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_data->render_buffers) : RID(); RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } @@ -633,7 +633,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color projection = correction * p_render_data->cam_projection; } - sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this); + sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this); RID sky_rid = env->sky; if (sky_rid.is_valid()) { @@ -653,9 +653,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (draw_sky || draw_sky_fog_only) { // !BAS! @TODO See if we can limit doing some things double and maybe even move this into _pre_opaque_render // and change Forward Clustered in the same way as we have here (but without using subpasses) - RENDER_TIMESTAMP("Setup Sky resolution buffers"); + RENDER_TIMESTAMP("Setup Sky Resolution Buffers"); - RD::get_singleton()->draw_command_begin_label("Setup Sky resolution buffers"); + RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers"); if (p_render_data->reflection_probe.is_valid()) { CameraMatrix correction; @@ -972,9 +972,9 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { /* */ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { - RENDER_TIMESTAMP("Setup Rendering Material"); + RENDER_TIMESTAMP("Setup Rendering 3D Material"); - RD::get_singleton()->draw_command_begin_label("Render Material"); + RD::get_singleton()->draw_command_begin_label("Render 3D Material"); _update_render_base_uniform_set(); @@ -997,7 +997,7 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, 0); @@ -1039,7 +1039,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<GeometryInstance *> &p_in RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_SECONDARY, nullptr, RID()); - RENDER_TIMESTAMP("Render Material"); + RENDER_TIMESTAMP("Render 3D Material"); { RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, rp_uniform_set, true, false); @@ -1089,7 +1089,7 @@ void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_ } void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { - RENDER_TIMESTAMP("Setup Render Collider Heightfield"); + RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1145,11 +1145,9 @@ void RenderForwardMobile::_update_render_base_uniform_set() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -1162,6 +1160,9 @@ void RenderForwardMobile::_update_render_base_uniform_set() { ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); + uniforms.push_back(u); } @@ -1169,7 +1170,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(scene_shader.shadow_sampler); + u.append_id(scene_shader.shadow_sampler); uniforms.push_back(u); } @@ -1196,7 +1197,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -1223,7 +1224,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { } break; } - u.ids.push_back(sampler); + u.append_id(sampler); uniforms.push_back(u); } @@ -1231,14 +1232,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_omni_light_buffer()); + u.append_id(get_omni_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_spot_light_buffer()); + u.append_id(get_spot_light_buffer()); uniforms.push_back(u); } @@ -1246,28 +1247,28 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_reflection_probe_buffer()); + u.append_id(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(get_directional_light_buffer()); + u.append_id(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_buffer); + u.append_id(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(scene_state.lightmap_capture_buffer); + u.append_id(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { @@ -1275,7 +1276,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { @@ -1283,14 +1284,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() { u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); - u.ids.push_back(decal_atlas); + u.append_id(decal_atlas); uniforms.push_back(u); } { RD::Uniform u; u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(get_decal_buffer()); + u.append_id(get_decal_buffer()); uniforms.push_back(u); } @@ -1298,7 +1299,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 14; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } 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 0b99948063..4dc56e8970 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 @@ -545,7 +545,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.renames["RIM"] = "rim"; actions.renames["RIM_TINT"] = "rim_tint"; actions.renames["CLEARCOAT"] = "clearcoat"; - actions.renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; + actions.renames["CLEARCOAT_ROUGHNESS"] = "clearcoat_roughness"; actions.renames["ANISOTROPY"] = "anisotropy"; actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; actions.renames["SSS_STRENGTH"] = "sss_strength"; @@ -594,7 +594,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n"; actions.usage_defines["RIM_TINT"] = "@RIM"; actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n"; - actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; + actions.usage_defines["CLEARCOAT_ROUGHNESS"] = "@CLEARCOAT"; actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n"; actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; actions.usage_defines["AO"] = "#define AO_USED\n"; @@ -649,15 +649,8 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n"; - bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); - if (!force_blinn) { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - } else { - actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; - } + actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; - actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; @@ -741,7 +734,7 @@ void fragment() { Vector<RD::Uniform> uniforms; RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(default_vec4_xform_buffer); + u.append_id(default_vec4_xform_buffer); u.binding = 0; uniforms.push_back(u); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 0f3daef371..38234cf0e7 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -931,7 +931,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 1; - u.ids.push_back(state.canvas_state_buffer); + u.append_id(state.canvas_state_buffer); uniforms.push_back(u); } @@ -939,7 +939,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(state.lights_uniform_buffer); + u.append_id(state.lights_uniform_buffer); uniforms.push_back(u); } @@ -947,7 +947,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 3; - u.ids.push_back(storage->decal_atlas_get_texture()); + u.append_id(storage->decal_atlas_get_texture()); uniforms.push_back(u); } @@ -955,7 +955,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 4; - u.ids.push_back(state.shadow_texture); + u.append_id(state.shadow_texture); uniforms.push_back(u); } @@ -963,7 +963,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 5; - u.ids.push_back(state.shadow_sampler); + u.append_id(state.shadow_sampler); uniforms.push_back(u); } @@ -980,7 +980,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo screen = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); } } - u.ids.push_back(screen); + u.append_id(screen); uniforms.push_back(u); } @@ -989,17 +989,15 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 7; RID sdf = storage->render_target_get_sdf_texture(p_to_render_target); - u.ids.push_back(sdf); + u.append_id(sdf); uniforms.push_back(u); } { //needs samplers for the material (uses custom textures) create them - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 8; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -1012,6 +1010,9 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 8, ids); + uniforms.push_back(u); } @@ -1019,7 +1020,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 9; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2567,7 +2568,7 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(storage->get_default_rd_storage_buffer()); + u.append_id(storage->get_default_rd_storage_buffer()); uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp index 2f8ef696cd..e8978e7dca 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp @@ -39,6 +39,9 @@ void RendererCompositorRD::prepare_for_blitting_render_targets() { void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen); + if (draw_list == RD::INVALID_ID) { + return; // Window is minimized and does not have valid swapchain, skip drawing without printing errors. + } for (int i = 0; i < p_amount; i++) { RID texture = storage->render_target_get_texture(p_render_targets[i].render_target); @@ -53,8 +56,8 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(blit.sampler); - u.ids.push_back(rd_texture); + u.append_id(blit.sampler); + u.append_id(rd_texture); uniforms.push_back(u); RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0); @@ -172,8 +175,8 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; u.binding = 0; - u.ids.push_back(blit.sampler); - u.ids.push_back(rd_texture); + u.append_id(blit.sampler); + u.append_id(rd_texture); uniforms.push_back(u); uset = RD::get_singleton()->uniform_set_create(uniforms, blit.shader.version_get_shader(blit.shader_version, BLIT_MODE_NORMAL), 0); } @@ -238,6 +241,8 @@ void RendererCompositorRD::set_boot_image(const Ref<Image> &p_image, const Color RendererCompositorRD *RendererCompositorRD::singleton = nullptr; RendererCompositorRD::RendererCompositorRD() { + uniform_set_cache = memnew(UniformSetCacheRD); + { String shader_cache_dir = Engine::get_singleton()->get_shader_cache_path(); if (shader_cache_dir.is_empty()) { @@ -298,5 +303,6 @@ RendererCompositorRD::RendererCompositorRD() { } RendererCompositorRD::~RendererCompositorRD() { + memdelete(uniform_set_cache); ShaderRD::set_shader_cache_dir(String()); } diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 9a992d5819..e526b95677 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -39,9 +39,11 @@ #include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h" #include "servers/rendering/renderer_rd/renderer_storage_rd.h" #include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" class RendererCompositorRD : public RendererCompositor { protected: + UniformSetCacheRD *uniform_set_cache; RendererCanvasRenderRD *canvas; RendererStorageRD *storage; RendererSceneRenderRD *scene; diff --git a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h index ed26fd467b..4e170b8cfb 100644 --- a/servers/rendering/renderer_rd/renderer_scene_environment_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_environment_rd.h @@ -135,15 +135,15 @@ public: /// SDFGI bool sdfgi_enabled = false; - int sdfgi_cascades = 6; + int sdfgi_cascades = 4; float sdfgi_min_cell_size = 0.2; bool sdfgi_use_occlusion = false; - float sdfgi_bounce_feedback = 0.0; - bool sdfgi_read_sky_light = false; + float sdfgi_bounce_feedback = 0.5; + bool sdfgi_read_sky_light = true; float sdfgi_energy = 1.0; float sdfgi_normal_bias = 1.1; float sdfgi_probe_bias = 1.1; - RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_DISABLED; + RS::EnvironmentSDFGIYScale sdfgi_y_scale = RS::ENV_SDFGI_Y_SCALE_75_PERCENT; /// Adjustments diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index 3069b1c379..8f0e1d36db 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -46,7 +46,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V min_cell_size = p_env->sdfgi_min_cell_size; uses_occlusion = p_env->sdfgi_use_occlusion; y_scale_mode = p_env->sdfgi_y_scale; - static const float y_scale[3] = { 1.0, 1.5, 2.0 }; + static const float y_scale[3] = { 2.0, 1.5, 1.0 }; y_mult = y_scale[y_scale_mode]; cascades.resize(num_cascades); probe_axis_count = SDFGI::PROBE_DIVISOR + 1; @@ -221,14 +221,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1 + u.append_id(render_sdf[(passes & 1) ? 1 : 0]); //if passes are even, we read from buffer 0, else we read from buffer 1 uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { @@ -236,7 +236,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; for (int j = 0; j < 8; j++) { - u.ids.push_back(render_occlusion[j]); + u.append_id(render_occlusion[j]); } uniforms.push_back(u); } @@ -244,21 +244,21 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; - u.ids.push_back(render_emission); + u.append_id(render_emission); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(render_emission_aniso); + u.append_id(render_emission_aniso); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; - u.ids.push_back(render_geom_facing); + u.append_id(render_geom_facing); uniforms.push_back(u); } @@ -266,28 +266,28 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; - u.ids.push_back(cascade.sdf_tex); + u.append_id(cascade.sdf_tex); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(occlusion_data); + u.append_id(occlusion_data); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 10; - u.ids.push_back(cascade.solid_cell_dispatch_buffer); + u.append_id(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 11; - u.ids.push_back(cascade.solid_cell_buffer); + u.append_id(cascade.solid_cell_buffer); uniforms.push_back(u); } @@ -300,42 +300,42 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_geom_facing); + u.append_id(render_geom_facing); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(render_emission); + u.append_id(render_emission); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; - u.ids.push_back(render_emission_aniso); + u.append_id(render_emission_aniso); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 5; - u.ids.push_back(cascade.solid_cell_dispatch_buffer); + u.append_id(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; - u.ids.push_back(cascade.solid_cell_buffer); + u.append_id(cascade.solid_cell_buffer); uniforms.push_back(u); } @@ -348,7 +348,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; for (int j = 0; j < 8; j++) { - u.ids.push_back(render_occlusion[j]); + u.append_id(render_occlusion[j]); } uniforms.push_back(u); } @@ -356,7 +356,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(occlusion_data); + u.append_id(occlusion_data); uniforms.push_back(u); } @@ -375,9 +375,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].sdf_tex); + u.append_id(cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -386,70 +386,70 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(cascade.solid_cell_dispatch_buffer); + u.append_id(cascade.solid_cell_dispatch_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(cascade.solid_cell_buffer); + u.append_id(cascade.solid_cell_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(cascade.light_data); + u.append_id(cascade.light_data); uniforms.push_back(u); } { RD::Uniform u; u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(cascade.light_aniso_0_tex); + u.append_id(cascade.light_aniso_0_tex); uniforms.push_back(u); } { RD::Uniform u; u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(cascade.light_aniso_1_tex); + u.append_id(cascade.light_aniso_1_tex); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(cascade.lights_buffer); + u.append_id(cascade.lights_buffer); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(lightprobe_texture); + u.append_id(lightprobe_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(occlusion_texture); + u.append_id(occlusion_texture); uniforms.push_back(u); } @@ -463,14 +463,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf[0]); + u.append_id(render_sdf[0]); uniforms.push_back(u); } @@ -483,14 +483,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf_half[0]); + u.append_id(render_sdf_half[0]); uniforms.push_back(u); } @@ -504,19 +504,22 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_sdf[0]); + u.append_id(render_sdf[0]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf[1]); + u.append_id(render_sdf[1]); uniforms.push_back(u); } jump_flood_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); - SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]); + RID aux0 = uniforms.write[0].get_id(0); + RID aux1 = uniforms.write[1].get_id(0); + uniforms.write[0].set_id(0, aux1); + uniforms.write[1].set_id(0, aux0); jump_flood_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); } //jump flood half uniform set @@ -526,19 +529,22 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_sdf_half[0]); + u.append_id(render_sdf_half[0]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf_half[1]); + u.append_id(render_sdf_half[1]); uniforms.push_back(u); } jump_flood_half_uniform_set[0] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); - SWAP(uniforms.write[0].ids.write[0], uniforms.write[1].ids.write[0]); + RID aux0 = uniforms.write[0].get_id(0); + RID aux1 = uniforms.write[1].get_id(0); + uniforms.write[0].set_id(0, aux1); + uniforms.write[1].set_id(0, aux0); jump_flood_half_uniform_set[1] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.preprocess.version_get_shader(gi->sdfgi_shader.preprocess_shader, SDFGIShader::PRE_PROCESS_JUMP_FLOOD), 0); } @@ -549,21 +555,21 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size + u.append_id(render_sdf_half[(passes & 1) ? 0 : 1]); //reverse pass order because half size uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass + u.append_id(render_sdf[(passes & 1) ? 0 : 1]); //reverse pass order because it needs an extra JFA pass uniforms.push_back(u); } @@ -578,7 +584,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(render_albedo); + u.append_id(render_albedo); uniforms.push_back(u); } { @@ -586,7 +592,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; for (int i = 0; i < 8; i++) { - u.ids.push_back(render_occlusion[i]); + u.append_id(render_occlusion[i]); } uniforms.push_back(u); } @@ -594,7 +600,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(render_geom_facing); + u.append_id(render_geom_facing); uniforms.push_back(u); } @@ -612,9 +618,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].sdf_tex); + u.append_id(cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -625,9 +631,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].light_tex); + u.append_id(cascades[j].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -638,9 +644,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].light_aniso_0_tex); + u.append_id(cascades[j].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -651,9 +657,9 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (j < cascades.size()) { - u.ids.push_back(cascades[j].light_aniso_1_tex); + u.append_id(cascades[j].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -662,7 +668,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 6; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -670,14 +676,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 7; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(lightprobe_data); + u.append_id(lightprobe_data); uniforms.push_back(u); } @@ -685,14 +691,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(cascades[i].lightprobe_history_tex); + u.append_id(cascades[i].lightprobe_history_tex); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; - u.ids.push_back(cascades[i].lightprobe_average_tex); + u.append_id(cascades[i].lightprobe_average_tex); uniforms.push_back(u); } @@ -700,14 +706,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(lightprobe_history_scroll); + u.append_id(lightprobe_history_scroll); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; - u.ids.push_back(lightprobe_average_scroll); + u.append_id(lightprobe_average_scroll); uniforms.push_back(u); } { @@ -723,14 +729,14 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V } else { parent_average = cascades[i - 1].lightprobe_average_tex; //to use something, but it won't be used } - u.ids.push_back(parent_average); + u.append_id(parent_average); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 14; - u.ids.push_back(ambient_texture); + u.append_id(ambient_texture); uniforms.push_back(u); } @@ -934,7 +940,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(p_sky->radiance); + u.append_id(p_sky->radiance); uniforms.push_back(u); } @@ -942,7 +948,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -1002,7 +1008,7 @@ void RendererSceneGIRD::SDFGI::store_probes() { push_constant.y_mult = y_mult; // Then store values into the lightprobe texture. Separating these steps has a small performance hit, but it allows for multiple bounces - RENDER_TIMESTAMP("Average Probes"); + RENDER_TIMESTAMP("Average SDFGI Probes"); RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.integrate_pipeline[SDFGIShader::INTEGRATE_MODE_STORE]); @@ -1110,9 +1116,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].sdf_tex); + u.append_id(cascades[i].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1123,9 +1129,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].light_tex); + u.append_id(cascades[i].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1136,9 +1142,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].light_aniso_0_tex); + u.append_id(cascades[i].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1149,9 +1155,9 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) { if (i < cascades.size()) { - u.ids.push_back(cascades[i].light_aniso_1_tex); + u.append_id(cascades[i].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -1160,35 +1166,35 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons RD::Uniform u; u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(occlusion_texture); + u.append_id(occlusion_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.ids.push_back(p_texture); + u.append_id(p_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(lightprobe_texture); + u.append_id(lightprobe_texture); uniforms.push_back(u); } debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0); @@ -1273,28 +1279,28 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr RD::Uniform u; u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(cascades_ubo); + u.append_id(cascades_ubo); uniforms.push_back(u); } { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(lightprobe_texture); + u.append_id(lightprobe_texture); uniforms.push_back(u); } { RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(occlusion_texture); + u.append_id(occlusion_texture); uniforms.push_back(u); } @@ -1555,14 +1561,14 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, if (cascade_next != cascade) { RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade"); - RENDER_TIMESTAMP(">SDFGI Update SDF"); + RENDER_TIMESTAMP("> SDFGI Update SDF"); //done rendering! must update SDF //clear dispatch indirect data SDFGIShader::PreprocessPushConstant push_constant; memset(&push_constant, 0, sizeof(SDFGIShader::PreprocessPushConstant)); - RENDER_TIMESTAMP("Scroll SDF"); + RENDER_TIMESTAMP("SDFGI Scroll SDF"); //scroll if (cascades[cascade].dirty_regions != SDFGI::Cascade::DIRTY_ALL) { @@ -1701,7 +1707,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, push_constant.half_size = true; { - RENDER_TIMESTAMP("SDFGI Jump Flood (Half Size)"); + RENDER_TIMESTAMP("SDFGI Jump Flood (Half-Size)"); uint32_t s = cascade_half_size; @@ -1723,7 +1729,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } } - RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half Size)"); + RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Half-Size)"); //continue with optimized jump flood for smaller reads RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); @@ -1759,7 +1765,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } else { //full size jumpflood - RENDER_TIMESTAMP("SDFGI Jump Flood"); + RENDER_TIMESTAMP("SDFGI Jump Flood (Full-Size)"); RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_INITIALIZE]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, sdf_initialize_uniform_set, 0); @@ -1790,7 +1796,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, } } - RENDER_TIMESTAMP("SDFGI Jump Flood Optimized"); + RENDER_TIMESTAMP("SDFGI Jump Flood Optimized (Full-Size)"); //continue with optimized jump flood for smaller reads RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.preprocess_pipeline[SDFGIShader::PRE_PROCESS_JUMP_FLOOD_OPTIMIZED]); @@ -1882,7 +1888,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, //finalize render and update sdf #endif - RENDER_TIMESTAMP("<SDFGI Update SDF"); + RENDER_TIMESTAMP("< SDFGI Update SDF"); RD::get_singleton()->draw_command_end_label(); } } @@ -1891,10 +1897,9 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32 RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but... - RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs"); + RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lights"); update_cascades(); - ; //need cascades updated for this SDFGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS]; uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS]; @@ -2074,14 +2079,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->voxel_gi_get_octree_buffer(probe)); + u.append_id(storage->voxel_gi_get_octree_buffer(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(storage->voxel_gi_get_data_buffer(probe)); + u.append_id(storage->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } @@ -2089,21 +2094,21 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 4; - u.ids.push_back(write_buffer); + u.append_id(write_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -2114,7 +2119,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; - u.ids.push_back(gi->voxel_gi_lights_uniform); + u.append_id(gi->voxel_gi_lights_uniform); copy_uniforms.push_back(u); } @@ -2126,7 +2131,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 5; - u.ids.push_back(texture); + u.append_id(texture); copy_uniforms.push_back(u); } mipmap.second_bounce_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, gi->voxel_gi_lighting_shader_version_shaders[VOXEL_GI_SHADER_VERSION_COMPUTE_SECOND_BOUNCE], 0); @@ -2139,7 +2144,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(mipmap.texture); + u.append_id(mipmap.texture); uniforms.push_back(u); } @@ -2214,7 +2219,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 3; - u.ids.push_back(gi->voxel_gi_lights_uniform); + u.append_id(gi->voxel_gi_lights_uniform); uniforms.push_back(u); } @@ -2222,56 +2227,56 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(dmap.albedo); + u.append_id(dmap.albedo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; - u.ids.push_back(dmap.normal); + u.append_id(dmap.normal); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; - u.ids.push_back(dmap.orm); + u.append_id(dmap.orm); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 8; - u.ids.push_back(dmap.fb_depth); + u.append_id(dmap.fb_depth); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(dmap.texture); + u.append_id(dmap.texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 12; - u.ids.push_back(dmap.depth); + u.append_id(dmap.depth); uniforms.push_back(u); } @@ -2287,14 +2292,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 5; - u.ids.push_back(dynamic_maps[dynamic_maps.size() - 1].texture); + u.append_id(dynamic_maps[dynamic_maps.size() - 1].texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 6; - u.ids.push_back(dynamic_maps[dynamic_maps.size() - 1].depth); + u.append_id(dynamic_maps[dynamic_maps.size() - 1].depth); uniforms.push_back(u); } @@ -2303,14 +2308,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 7; - u.ids.push_back(dmap.texture); + u.append_id(dmap.texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(dmap.depth); + u.append_id(dmap.depth); uniforms.push_back(u); } } @@ -2319,14 +2324,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 9; - u.ids.push_back(storage->voxel_gi_get_sdf_texture(probe)); + u.append_id(storage->voxel_gi_get_sdf_texture(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -2335,7 +2340,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 11; - u.ids.push_back(mipmaps[dmap.mipmap].texture); + u.append_id(mipmaps[dmap.mipmap].texture); uniforms.push_back(u); } } @@ -2748,21 +2753,21 @@ void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->voxel_gi_get_data_buffer(probe)); + u.append_id(storage->voxel_gi_get_data_buffer(probe)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.ids.push_back(texture); + u.append_id(texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 3; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -2919,14 +2924,14 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_WHITE)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 1; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -3179,9 +3184,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].sdf_tex); + u.append_id(rb->sdfgi->cascades[j].sdf_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3192,9 +3197,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].light_tex); + u.append_id(rb->sdfgi->cascades[j].light_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3205,9 +3210,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_0_tex); + u.append_id(rb->sdfgi->cascades[j].light_aniso_0_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3218,9 +3223,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) { if (rb->sdfgi && j < rb->sdfgi->cascades.size()) { - u.ids.push_back(rb->sdfgi->cascades[j].light_aniso_1_tex); + u.append_id(rb->sdfgi->cascades[j].light_aniso_1_tex); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } } uniforms.push_back(u); @@ -3230,9 +3235,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 5; if (rb->sdfgi) { - u.ids.push_back(rb->sdfgi->occlusion_texture); + u.append_id(rb->sdfgi->occlusion_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE)); } uniforms.push_back(u); } @@ -3240,14 +3245,14 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 6; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 7; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); } @@ -3255,7 +3260,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(rb->ambient_buffer); + u.append_id(rb->ambient_buffer); uniforms.push_back(u); } @@ -3263,7 +3268,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 10; - u.ids.push_back(rb->reflection_buffer); + u.append_id(rb->reflection_buffer); uniforms.push_back(u); } @@ -3272,9 +3277,9 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 11; if (rb->sdfgi) { - u.ids.push_back(rb->sdfgi->lightprobe_texture); + u.append_id(rb->sdfgi->lightprobe_texture); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE)); } uniforms.push_back(u); } @@ -3282,14 +3287,14 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; - u.ids.push_back(rb->depth_texture); + u.append_id(rb->depth_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 13; - u.ids.push_back(p_normal_roughness_buffer); + u.append_id(p_normal_roughness_buffer); uniforms.push_back(u); } { @@ -3297,21 +3302,21 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 14; RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); - u.ids.push_back(buffer); + u.append_id(buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 15; - u.ids.push_back(sdfgi_ubo); + u.append_id(sdfgi_ubo); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 16; - u.ids.push_back(rb->gi.voxel_gi_buffer); + u.append_id(rb->gi.voxel_gi_buffer); uniforms.push_back(u); } { @@ -3319,7 +3324,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 17; for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) { - u.ids.push_back(rb->gi.voxel_gi_textures[i]); + u.append_id(rb->gi.voxel_gi_textures[i]); } uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h index 5e55262798..f2d1a17099 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h @@ -250,8 +250,6 @@ private: float cos_spot_angle; float inv_spot_attenuation; float radius; - - float shadow_color[4]; }; struct DirectLightPushConstant { @@ -392,7 +390,7 @@ public: return voxel_gi->texture; }; - RS::VoxelGIQuality voxel_gi_quality = RS::VOXEL_GI_QUALITY_HIGH; + RS::VoxelGIQuality voxel_gi_quality = RS::VOXEL_GI_QUALITY_LOW; /* SDFGI */ @@ -504,12 +502,12 @@ public: RID cascades_ubo; bool uses_occlusion = false; - float bounce_feedback = 0.0; - bool reads_sky = false; + float bounce_feedback = 0.5; + bool reads_sky = true; float energy = 1.0; float normal_bias = 1.1; float probe_bias = 1.1; - RS::EnvironmentSDFGIYScale y_scale_mode = RS::ENV_SDFGI_Y_SCALE_DISABLED; + RS::EnvironmentSDFGIYScale y_scale_mode = RS::ENV_SDFGI_Y_SCALE_75_PERCENT; float y_mult = 1.0; @@ -536,7 +534,7 @@ public: }; RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16; - RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_10_FRAMES; + RS::EnvironmentSDFGIFramesToConverge sdfgi_frames_to_converge = RS::ENV_SDFGI_CONVERGE_IN_30_FRAMES; RS::EnvironmentSDFGIFramesToUpdateLight sdfgi_frames_to_update_light = RS::ENV_SDFGI_UPDATE_LIGHT_IN_4_FRAMES; float sdfgi_solid_cell_ratio = 0.25; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 43a1812f89..6296e10962 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1818,11 +1818,14 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { if (rb->blur[i].mipmaps[m].fb.is_valid()) { RD::get_singleton()->free(rb->blur[i].mipmaps[m].fb); } - if (rb->blur[i].mipmaps[m].half_fb.is_valid()) { - RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_fb); - } - if (rb->blur[i].mipmaps[m].half_texture.is_valid()) { - RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_texture); + // texture and framebuffer in both blur mipmaps are shared, so only free from the first one + if (i == 0) { + if (rb->blur[i].mipmaps[m].half_fb.is_valid()) { + RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_fb); + } + if (rb->blur[i].mipmaps[m].half_texture.is_valid()) { + RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_texture); + } } } rb->blur[i].mipmaps.clear(); @@ -1977,7 +1980,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb rb->ssr.normal_scaled = RD::get_singleton()->texture_create(tf, RD::TextureView()); } - if (ssr_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) { + if (ssr_roughness_quality != RS::ENV_SSR_ROUGHNESS_QUALITY_DISABLED && !rb->ssr.blur_radius[0].is_valid()) { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8_UNORM; tf.width = rb->internal_width / 2; @@ -3263,7 +3266,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const r_directional_light_count = 0; r_positional_light_count = 0; - sky.sky_scene_state.ubo.directional_light_count = 0; Plane camera_plane(-p_camera_transform.basis.get_axis(Vector3::AXIS_Z).normalized(), p_camera_transform.origin); @@ -3284,42 +3286,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const RS::LightType type = storage->light_get_type(base); switch (type) { case RS::LIGHT_DIRECTIONAL: { - // Copy to SkyDirectionalLightData - if (r_directional_light_count < sky.sky_scene_state.max_directional_lights) { - RendererSceneSkyRD::SkyDirectionalLightData &sky_light_data = sky.sky_scene_state.directional_lights[r_directional_light_count]; - Transform3D light_transform = li->transform; - Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); - - sky_light_data.direction[0] = world_direction.x; - sky_light_data.direction[1] = world_direction.y; - sky_light_data.direction[2] = -world_direction.z; - - float sign = storage->light_is_negative(base) ? -1 : 1; - sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); - - Color linear_col = storage->light_get_color(base).to_linear(); - sky_light_data.color[0] = linear_col.r; - sky_light_data.color[1] = linear_col.g; - sky_light_data.color[2] = linear_col.b; - - sky_light_data.enabled = true; - - float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); - if (angular_diameter > 0.0) { - // I know tan(0) is 0, but let's not risk it with numerical precision. - // technically this will keep expanding until reaching the sun, but all we care - // is expand until we reach the radius of the near plane (there can't be more occluders than that) - angular_diameter = Math::tan(Math::deg2rad(angular_diameter)); - if (storage->light_has_shadow(base)) { - r_directional_light_soft_shadows = true; - } - } else { - angular_diameter = 0.0; - } - sky_light_data.size = angular_diameter; - sky.sky_scene_state.ubo.directional_light_count++; - } - if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) { continue; } @@ -3350,43 +3316,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.size = 1.0 - Math::cos(Math::deg2rad(size)); //angle to cosine offset - Color shadow_col = storage->light_get_shadow_color(base).to_linear(); - if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) { - light_data.shadow_color1[0] = 1.0; - light_data.shadow_color1[1] = 0.0; - light_data.shadow_color1[2] = 0.0; - light_data.shadow_color1[3] = 1.0; - light_data.shadow_color2[0] = 0.0; - light_data.shadow_color2[1] = 1.0; - light_data.shadow_color2[2] = 0.0; - light_data.shadow_color2[3] = 1.0; - light_data.shadow_color3[0] = 0.0; - light_data.shadow_color3[1] = 0.0; - light_data.shadow_color3[2] = 1.0; - light_data.shadow_color3[3] = 1.0; - light_data.shadow_color4[0] = 1.0; - light_data.shadow_color4[1] = 1.0; - light_data.shadow_color4[2] = 0.0; - light_data.shadow_color4[3] = 1.0; - - } else { - light_data.shadow_color1[0] = shadow_col.r; - light_data.shadow_color1[1] = shadow_col.g; - light_data.shadow_color1[2] = shadow_col.b; - light_data.shadow_color1[3] = 1.0; - light_data.shadow_color2[0] = shadow_col.r; - light_data.shadow_color2[1] = shadow_col.g; - light_data.shadow_color2[2] = shadow_col.b; - light_data.shadow_color2[3] = 1.0; - light_data.shadow_color3[0] = shadow_col.r; - light_data.shadow_color3[1] = shadow_col.g; - light_data.shadow_color3[2] = shadow_col.b; - light_data.shadow_color3[3] = 1.0; - light_data.shadow_color4[0] = shadow_col.r; - light_data.shadow_color4[1] = shadow_col.g; - light_data.shadow_color4[2] = shadow_col.b; - light_data.shadow_color4[3] = 1.0; + WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet."); } light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base); @@ -3397,6 +3328,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const // technically this will keep expanding until reaching the sun, but all we care // is expand until we reach the radius of the near plane (there can't be more occluders than that) angular_diameter = Math::tan(Math::deg2rad(angular_diameter)); + if (storage->light_has_shadow(base)) { + r_directional_light_soft_shadows = true; + } } else { angular_diameter = 0.0; } @@ -3471,8 +3405,22 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const continue; } + const real_t distance = camera_plane.distance_to(li->transform.origin); + + if (storage->light_is_distance_fade_enabled(li->light)) { + const float fade_begin = storage->light_get_distance_fade_begin(li->light); + const float fade_length = storage->light_get_distance_fade_length(li->light); + + if (distance > fade_begin) { + if (distance > fade_begin + fade_length) { + // Out of range, don't draw this light to improve performance. + continue; + } + } + } + cluster.omni_light_sort[cluster.omni_light_count].instance = li; - cluster.omni_light_sort[cluster.omni_light_count].depth = camera_plane.distance_to(li->transform.origin); + cluster.omni_light_sort[cluster.omni_light_count].depth = distance; cluster.omni_light_count++; } break; case RS::LIGHT_SPOT: { @@ -3480,8 +3428,22 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const continue; } + const real_t distance = camera_plane.distance_to(li->transform.origin); + + if (storage->light_is_distance_fade_enabled(li->light)) { + const float fade_begin = storage->light_get_distance_fade_begin(li->light); + const float fade_length = storage->light_get_distance_fade_length(li->light); + + if (distance > fade_begin) { + if (distance > fade_begin + fade_length) { + // Out of range, don't draw this light to improve performance. + continue; + } + } + } + cluster.spot_light_sort[cluster.spot_light_count].instance = li; - cluster.spot_light_sort[cluster.spot_light_count].depth = camera_plane.distance_to(li->transform.origin); + cluster.spot_light_sort[cluster.spot_light_count].depth = distance; cluster.spot_light_count++; } break; } @@ -3525,7 +3487,24 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.attenuation = storage->light_get_param(base, RS::LIGHT_PARAM_ATTENUATION); - float energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI; + // Reuse fade begin, fade length and distance for shadow LOD determination later. + float fade_begin = 0.0; + float fade_length = 0.0; + real_t distance = 0.0; + + float fade = 1.0; + if (storage->light_is_distance_fade_enabled(li->light)) { + fade_begin = storage->light_get_distance_fade_begin(li->light); + fade_length = storage->light_get_distance_fade_length(li->light); + distance = camera_plane.distance_to(li->transform.origin); + + if (distance > fade_begin) { + // Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player. + fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length); + } + } + + float energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY) * Math_PI * fade; light_data.color[0] = linear_col.r * energy; light_data.color[1] = linear_col.g * energy; @@ -3586,7 +3565,17 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.projector_rect[3] = 0; } - if (shadow_atlas && shadow_atlas->shadow_owners.has(li->self)) { + const bool needs_shadow = shadow_atlas && shadow_atlas->shadow_owners.has(li->self); + + bool in_shadow_range = true; + if (needs_shadow && storage->light_is_distance_fade_enabled(li->light)) { + if (distance > storage->light_get_distance_fade_shadow(li->light)) { + // Out of range, don't draw shadows to improve performance. + in_shadow_range = false; + } + } + + if (needs_shadow && in_shadow_range) { // fill in the shadow information light_data.shadow_enabled = true; @@ -4095,7 +4084,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e return; } - RENDER_TIMESTAMP(">Volumetric Fog"); + RENDER_TIMESTAMP("> Volumetric Fog"); RD::get_singleton()->draw_command_begin_label("Volumetric Fog"); if (env && env->volumetric_fog_enabled && !rb->volumetric_fog) { @@ -4157,7 +4146,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.ids.push_back(rb->volumetric_fog->fog_map); + u.append_id(rb->volumetric_fog->fog_map); uniforms.push_back(u); } @@ -4167,7 +4156,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e if (p_fog_volumes.size() > 0) { RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog Volumes"); - RENDER_TIMESTAMP("Render Fog Volumes"); + RENDER_TIMESTAMP("Render FogVolumes"); VolumetricFogShader::VolumeUBO params; @@ -4222,7 +4211,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 1; - u.ids.push_back(rb->volumetric_fog->emissive_map); + u.append_id(rb->volumetric_fog->emissive_map); uniforms.push_back(u); } @@ -4230,7 +4219,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 2; - u.ids.push_back(volumetric_fog.volume_ubo); + u.append_id(volumetric_fog.volume_ubo); uniforms.push_back(u); } @@ -4242,7 +4231,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 3; - u.ids.push_back(rb->volumetric_fog->density_map); + u.append_id(rb->volumetric_fog->density_map); uniforms.push_back(u); } @@ -4254,7 +4243,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 4; - u.ids.push_back(rb->volumetric_fog->light_map); + u.append_id(rb->volumetric_fog->light_map); uniforms.push_back(u); } @@ -4375,9 +4364,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.binding = 1; ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas); if (shadow_atlas == nullptr || shadow_atlas->depth.is_null()) { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } else { - u.ids.push_back(shadow_atlas->depth); + u.append_id(shadow_atlas->depth); } uniforms.push_back(u); @@ -4389,9 +4378,9 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; if (directional_shadow.depth.is_valid()) { - u.ids.push_back(directional_shadow.depth); + u.append_id(directional_shadow.depth); } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK)); } uniforms.push_back(u); copy_uniforms.push_back(u); @@ -4401,7 +4390,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 3; - u.ids.push_back(get_omni_light_buffer()); + u.append_id(get_omni_light_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4409,7 +4398,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 4; - u.ids.push_back(get_spot_light_buffer()); + u.append_id(get_spot_light_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4418,7 +4407,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 5; - u.ids.push_back(get_directional_light_buffer()); + u.append_id(get_directional_light_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4427,7 +4416,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 6; - u.ids.push_back(rb->cluster_builder->get_cluster_buffer()); + u.append_id(rb->cluster_builder->get_cluster_buffer()); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4436,7 +4425,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 7; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4445,7 +4434,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 8; - u.ids.push_back(rb->volumetric_fog->light_density_map); + u.append_id(rb->volumetric_fog->light_density_map); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4454,7 +4443,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(rb->volumetric_fog->fog_map); + u.append_id(rb->volumetric_fog->fog_map); uniforms.push_back(u); } @@ -4462,7 +4451,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 9; - u.ids.push_back(rb->volumetric_fog->prev_light_density_map); + u.append_id(rb->volumetric_fog->prev_light_density_map); copy_uniforms.push_back(u); } @@ -4470,7 +4459,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 10; - u.ids.push_back(shadow_sampler); + u.append_id(shadow_sampler); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4479,7 +4468,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 11; - u.ids.push_back(render_buffers_get_voxel_gi_buffer(p_render_buffers)); + u.append_id(render_buffers_get_voxel_gi_buffer(p_render_buffers)); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4489,7 +4478,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 12; for (int i = 0; i < RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES; i++) { - u.ids.push_back(rb->gi.voxel_gi_textures[i]); + u.append_id(rb->gi.voxel_gi_textures[i]); } uniforms.push_back(u); copy_uniforms.push_back(u); @@ -4498,7 +4487,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 13; - u.ids.push_back(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); + u.append_id(storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED)); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4506,7 +4495,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 14; - u.ids.push_back(volumetric_fog.params_ubo); + u.append_id(volumetric_fog.params_ubo); uniforms.push_back(u); copy_uniforms.push_back(u); } @@ -4514,7 +4503,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 15; - u.ids.push_back(rb->volumetric_fog->prev_light_density_map); + u.append_id(rb->volumetric_fog->prev_light_density_map); uniforms.push_back(u); } { @@ -4525,7 +4514,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 16; - u.ids.push_back(rb->volumetric_fog->density_map); + u.append_id(rb->volumetric_fog->density_map); uniforms.push_back(u); } { @@ -4536,7 +4525,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 17; - u.ids.push_back(rb->volumetric_fog->light_map); + u.append_id(rb->volumetric_fog->light_map); uniforms.push_back(u); } @@ -4548,7 +4537,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.uniform_type = RD::UNIFORM_TYPE_IMAGE; #endif u.binding = 18; - u.ids.push_back(rb->volumetric_fog->emissive_map); + u.append_id(rb->volumetric_fog->emissive_map); uniforms.push_back(u); } @@ -4558,7 +4547,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e u.binding = 19; RID radiance_texture = storage->texture_rd_get_default(is_using_radiance_cubemap_array() ? RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK : RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK); RID sky_texture = env->sky.is_valid() ? sky.sky_get_radiance_texture_rd(env->sky) : RID(); - u.ids.push_back(sky_texture.is_valid() ? sky_texture : radiance_texture); + u.append_id(sky_texture.is_valid() ? sky_texture : radiance_texture); uniforms.push_back(u); } @@ -4566,7 +4555,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e rb->volumetric_fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0); - SWAP(uniforms.write[7].ids.write[0], uniforms.write[8].ids.write[0]); + RID aux7 = uniforms.write[7].get_id(0); + RID aux8 = uniforms.write[8].get_id(0); + + uniforms.write[7].set_id(0, aux8); + uniforms.write[8].set_id(0, aux7); rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, 0), 0); } @@ -4581,7 +4574,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; - u.ids.push_back(gi.sdfgi_ubo); + u.append_id(gi.sdfgi_ubo); uniforms.push_back(u); } @@ -4589,7 +4582,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - u.ids.push_back(rb->sdfgi->ambient_texture); + u.append_id(rb->sdfgi->ambient_texture); uniforms.push_back(u); } @@ -4597,7 +4590,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.ids.push_back(rb->sdfgi->occlusion_texture); + u.append_id(rb->sdfgi->occlusion_texture); uniforms.push_back(u); } @@ -4761,7 +4754,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER); - RENDER_TIMESTAMP("<Volumetric Fog"); + RENDER_TIMESTAMP("< Volumetric Fog"); RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_command_end_label(); @@ -4850,7 +4843,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool bool render_gi = p_render_data->render_buffers.is_valid() && p_use_gi; if (render_shadows && render_gi) { - RENDER_TIMESTAMP("Render GI + Render Shadows (parallel)"); + RENDER_TIMESTAMP("Render GI + Render Shadows (Parallel)"); } else if (render_shadows) { RENDER_TIMESTAMP("Render Shadows"); } else if (render_gi) { @@ -5730,11 +5723,9 @@ void fog() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -5747,6 +5738,8 @@ void fog() { ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); uniforms.push_back(u); } @@ -5754,7 +5747,7 @@ void fog() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 899d2d763d..4a86ced322 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -293,7 +293,7 @@ private: uint32_t smallest_subdiv = 0; int size = 0; - bool use_16_bits = false; + bool use_16_bits = true; RID depth; RID fb; //for copying @@ -333,7 +333,7 @@ private: int light_count = 0; int size = 0; - bool use_16_bits = false; + bool use_16_bits = true; int current_light = 0; } directional_shadow; @@ -428,7 +428,7 @@ private: bool glow_bicubic_upscale = false; bool glow_high_quality = false; - RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGNESS_QUALITY_LOW; + RS::EnvironmentSSRRoughnessQuality ssr_roughness_quality = RS::ENV_SSR_ROUGHNESS_QUALITY_LOW; mutable RID_Owner<RendererSceneEnvironmentRD, true> environment_owner; @@ -678,10 +678,6 @@ private: float shadow_range_begin[4]; float shadow_split_offsets[4]; float shadow_matrices[4][16]; - float shadow_color1[4]; - float shadow_color2[4]; - float shadow_color3[4]; - float shadow_color4[4]; float uv_scale1[2]; float uv_scale2[2]; float uv_scale3[2]; @@ -981,7 +977,7 @@ public: /* SHADOW ATLAS API */ virtual RID shadow_atlas_create() override; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) override; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override; virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) override; _FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) { @@ -1002,7 +998,7 @@ public: return Size2(atlas->size, atlas->size); } - virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) override; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override; virtual int get_directional_light_shadow_size(RID p_light_intance) override; virtual void set_directional_shadow_count(int p_count) override; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index f6f39230f8..e8d2ff9c8a 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -473,12 +473,13 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS } RD::get_singleton()->draw_command_end_label(); // Filter radiance } else { + RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); } - + RD::get_singleton()->draw_command_end_label(); // Downsample Radiance Vector<RID> views; if (p_use_arrays) { for (int i = 1; i < layers.size(); i++) { @@ -489,8 +490,9 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS views.push_back(layers[0].views[i]); } } - + RD::get_singleton()->draw_command_begin_label("Fast filter radiance"); effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays); + RD::get_singleton()->draw_command_end_label(); // Filter radiance } } @@ -500,12 +502,25 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren bool prefer_raster_effects = effects->get_prefer_raster_effects(); if (prefer_raster_effects) { - // Need to ask clayjohn but p_cube_side is set to 10, looks like in the compute shader we're doing all 6 sides in one call - // here we need to do them one by one so ignoring p_cube_side + if (p_base_layer == 1) { + RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); + for (int k = 0; k < 6; k++) { + effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size); + } + + for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { + for (int k = 0; k < 6; k++) { + effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size); + } + } + RD::get_singleton()->draw_command_end_label(); // Downsample Radiance + } + + RD::get_singleton()->draw_command_begin_label("High Quality filter radiance"); if (p_use_arrays) { for (int k = 0; k < 6; k++) { effects->cubemap_roughness_raster( - radiance_base_cubemap, + downsampled_radiance_cubemap, layers[p_base_layer].mipmaps[0].framebuffers[k], k, p_sky_ggx_samples_quality, @@ -515,7 +530,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren } else { for (int k = 0; k < 6; k++) { effects->cubemap_roughness_raster( - layers[0].views[p_base_layer - 1], + downsampled_radiance_cubemap, layers[0].mipmaps[p_base_layer].framebuffers[k], k, p_sky_ggx_samples_quality, @@ -524,12 +539,22 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren } } } else { + if (p_base_layer == 1) { + RD::get_singleton()->draw_command_begin_label("Downsample radiance map"); + effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size); + + for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) { + effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size); + } + RD::get_singleton()->draw_command_end_label(); // Downsample Radiance + } + + RD::get_singleton()->draw_command_begin_label("High Quality filter radiance"); if (p_use_arrays) { - //render directly to the layers - effects->cubemap_roughness(radiance_base_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x); + effects->cubemap_roughness(downsampled_radiance_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x); } else { effects->cubemap_roughness( - layers[0].views[p_base_layer - 1], + downsampled_radiance_cubemap, layers[0].views[p_base_layer], p_cube_side, p_sky_ggx_samples_quality, @@ -537,6 +562,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren layers[0].mipmaps[p_base_layer].size.x); } } + RD::get_singleton()->draw_command_end_label(); // Filter radiance } void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end) { @@ -604,9 +630,9 @@ RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextu u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; if (radiance.is_valid() && p_version <= SKY_TEXTURE_SET_QUARTER_RES) { - u.ids.push_back(radiance); + u.append_id(radiance); } else { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } uniforms.push_back(u); } @@ -616,15 +642,15 @@ RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextu u.binding = 1; // half res if (half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) { if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(reflection.layers[0].views[1]); + u.append_id(reflection.layers[0].views[1]); } else { - u.ids.push_back(half_res_pass); + u.append_id(half_res_pass); } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); @@ -635,15 +661,15 @@ RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextu u.binding = 2; // quarter res if (quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) { if (p_version >= SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(reflection.layers[0].views[2]); + u.append_id(reflection.layers[0].views[2]); } else { - u.ids.push_back(quarter_res_pass); + u.append_id(quarter_res_pass); } } else { if (p_version < SKY_TEXTURE_SET_CUBEMAP) { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); } else { - u.ids.push_back(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(p_storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); } } uniforms.push_back(u); @@ -892,11 +918,9 @@ void sky() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 0; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -909,6 +933,9 @@ void sky() { ids_ptr[9] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 0, ids); + uniforms.push_back(u); } @@ -916,7 +943,7 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(storage->global_variables_get_storage_buffer()); + u.append_id(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -924,7 +951,7 @@ void sky() { RD::Uniform u; u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(sky_scene_state.uniform_buffer); + u.append_id(sky_scene_state.uniform_buffer); uniforms.push_back(u); } @@ -932,7 +959,7 @@ void sky() { RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.ids.push_back(sky_scene_state.directional_light_buffer); + u.append_id(sky_scene_state.directional_light_buffer); uniforms.push_back(u); } @@ -946,7 +973,7 @@ void sky() { u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID vfog = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); - u.ids.push_back(vfog); + u.append_id(vfog); uniforms.push_back(u); } @@ -979,21 +1006,21 @@ void sky() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 0; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 2; - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); uniforms.push_back(u); } @@ -1040,8 +1067,8 @@ RendererSceneSkyRD::~RendererSceneSkyRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency } -void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { - ERR_FAIL_COND(!p_env); // I guess without an environment we also can't have a sky... +void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { + ERR_FAIL_COND(!p_env); SkyMaterialData *material = nullptr; Sky *sky = get_sky(p_env->sky); @@ -1122,15 +1149,67 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b } if (shader_data->uses_light) { + sky_scene_state.ubo.directional_light_count = 0; + // Run through the list of lights in the scene and pick out the Directional Lights. + // This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called + // after the depth prepass, but this runs before the depth prepass + for (int i = 0; i < (int)p_lights.size(); i++) { + RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_lights[i]); + if (!li) { + continue; + } + RID base = li->light; + + ERR_CONTINUE(base.is_null()); + + RS::LightType type = storage->light_get_type(base); + if (type == RS::LIGHT_DIRECTIONAL) { + SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count]; + Transform3D light_transform = li->transform; + Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized(); + + sky_light_data.direction[0] = world_direction.x; + sky_light_data.direction[1] = world_direction.y; + sky_light_data.direction[2] = world_direction.z; + + float sign = storage->light_is_negative(base) ? -1 : 1; + sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY); + + Color linear_col = storage->light_get_color(base).to_linear(); + sky_light_data.color[0] = linear_col.r; + sky_light_data.color[1] = linear_col.g; + sky_light_data.color[2] = linear_col.b; + + sky_light_data.enabled = true; + + float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE); + if (angular_diameter > 0.0) { + // I know tan(0) is 0, but let's not risk it with numerical precision. + // technically this will keep expanding until reaching the sun, but all we care + // is expand until we reach the radius of the near plane (there can't be more occluders than that) + angular_diameter = Math::tan(Math::deg2rad(angular_diameter)); + } else { + angular_diameter = 0.0; + } + sky_light_data.size = angular_diameter; + sky_scene_state.ubo.directional_light_count++; + if (sky_scene_state.ubo.directional_light_count >= sky_scene_state.max_directional_lights) { + break; + } + } + } // Check whether the directional_light_buffer changes bool light_data_dirty = false; + // Light buffer is dirty if we have fewer or more lights + // If we have fewer lights, make sure that old lights are disabled if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) { light_data_dirty = true; for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) { sky_scene_state.directional_lights[i].enabled = false; } } + if (!light_data_dirty) { for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) { if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] || diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h index d81a415c2d..13d24e2508 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h @@ -292,7 +292,7 @@ public: void set_texture_format(RD::DataFormat p_texture_format); ~RendererSceneSkyRD(); - void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); + void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index f345001539..e4ddc1b41f 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -1320,10 +1320,10 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas t = texture_owner.get_or_null(ct->diffuse); if (!t) { - u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); ct->size_cache = Size2i(1, 1); } else { - u.ids.push_back(t->rd_texture); + u.append_id(t->rd_texture); ct->size_cache = Size2i(t->width_2d, t->height_2d); } uniforms.push_back(u); @@ -1335,10 +1335,10 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas t = texture_owner.get_or_null(ct->normal_map); if (!t) { - u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL)); + u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL)); ct->use_normal_cache = false; } else { - u.ids.push_back(t->rd_texture); + u.append_id(t->rd_texture); ct->use_normal_cache = true; } uniforms.push_back(u); @@ -1350,10 +1350,10 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas t = texture_owner.get_or_null(ct->specular); if (!t) { - u.ids.push_back(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); + u.append_id(texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE)); ct->use_specular_cache = false; } else { - u.ids.push_back(t->rd_texture); + u.append_id(t->rd_texture); ct->use_specular_cache = true; } uniforms.push_back(u); @@ -1362,7 +1362,7 @@ bool RendererStorageRD::canvas_texture_get_uniform_set(RID p_texture, RS::Canvas RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; u.binding = 3; - u.ids.push_back(sampler_rd_get_default(filter, repeat)); + u.append_id(sampler_rd_get_default(filter, repeat)); uniforms.push_back(u); } @@ -2933,7 +2933,7 @@ bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<St RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.binding = 0; - u.ids.push_back(uniform_buffer); + u.append_id(uniform_buffer); uniforms.push_back(u); } @@ -2946,10 +2946,10 @@ bool RendererStorageRD::MaterialData::update_parameters_uniform_set(const Map<St u.binding = 1 + k; if (array_size > 0) { for (int j = 0; j < array_size; j++) { - u.ids.push_back(textures[k++]); + u.append_id(textures[k++]); } } else { - u.ids.push_back(textures[k++]); + u.append_id(textures[k++]); } uniforms.push_back(u); } @@ -3155,7 +3155,7 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(s->vertex_buffer); + u.append_id(s->vertex_buffer); uniforms.push_back(u); } { @@ -3163,9 +3163,9 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; if (s->skin_buffer.is_valid()) { - u.ids.push_back(s->skin_buffer); + u.append_id(s->skin_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -3174,9 +3174,9 @@ void RendererStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_su u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; if (s->blend_shape_buffer.is_valid()) { - u.ids.push_back(s->blend_shape_buffer); + u.append_id(s->blend_shape_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -3578,15 +3578,15 @@ void RendererStorageRD::mesh_instance_set_blend_shape_weight(RID p_mesh_instance void RendererStorageRD::_mesh_instance_clear(MeshInstance *mi) { for (uint32_t i = 0; i < mi->surfaces.size(); i++) { - if (mi->surfaces[i].vertex_buffer.is_valid()) { - RD::get_singleton()->free(mi->surfaces[i].vertex_buffer); - } if (mi->surfaces[i].versions) { for (uint32_t j = 0; j < mi->surfaces[i].version_count; j++) { RD::get_singleton()->free(mi->surfaces[i].versions[j].vertex_array); } memfree(mi->surfaces[i].versions); } + if (mi->surfaces[i].vertex_buffer.is_valid()) { + RD::get_singleton()->free(mi->surfaces[i].vertex_buffer); + } } mi->surfaces.clear(); @@ -3618,7 +3618,7 @@ void RendererStorageRD::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, RD::Uniform u; u.binding = 1; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(s.vertex_buffer); + u.append_id(s.vertex_buffer); uniforms.push_back(u); } { @@ -3626,9 +3626,9 @@ void RendererStorageRD::_mesh_instance_add_surface(MeshInstance *mi, Mesh *mesh, u.binding = 2; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; if (mi->blend_weights_buffer.is_valid()) { - u.ids.push_back(mi->blend_weights_buffer); + u.append_id(mi->blend_weights_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -4522,6 +4522,8 @@ void RendererStorageRD::_particles_free_data(Particles *particles) { particles->particle_instance_buffer = RID(); } + particles->userdata_count = 0; + if (particles->frame_params_buffer.is_valid()) { RD::get_singleton()->free(particles->frame_params_buffer); particles->frame_params_buffer = RID(); @@ -4716,6 +4718,14 @@ void RendererStorageRD::particles_set_process_material(RID p_particles, RID p_ma ERR_FAIL_COND(!particles); particles->process_material = p_material; + particles->dependency.changed_notify(DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed +} + +RID RendererStorageRD::particles_get_process_material(RID p_particles) const { + Particles *particles = particles_owner.get_or_null(p_particles); + ERR_FAIL_COND_V(!particles, RID()); + + return particles->process_material; } void RendererStorageRD::particles_set_draw_order(RID p_particles, RS::ParticlesDrawOrder p_order) { @@ -4852,10 +4862,13 @@ AABB RendererStorageRD::particles_get_current_aabb(RID p_particles) { if (buffer.size()) { bool first = true; - const ParticleData *particle_data = reinterpret_cast<const ParticleData *>(buffer.ptr()); + const uint8_t *data_ptr = (const uint8_t *)buffer.ptr(); + uint32_t particle_data_size = sizeof(ParticleData) + sizeof(float) * particles->userdata_count; + for (int i = 0; i < total_amount; i++) { - if (particle_data[i].active) { - Vector3 pos = Vector3(particle_data[i].xform[12], particle_data[i].xform[13], particle_data[i].xform[14]); + const ParticleData &particle_data = *(const ParticleData *)&data_ptr[particle_data_size * i]; + if (particle_data.active) { + Vector3 pos = Vector3(particle_data.xform[12], particle_data.xform[13], particle_data.xform[14]); if (!particles->use_local_coords) { pos = inv.xform(pos); } @@ -4940,14 +4953,14 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(p_particles->frame_params_buffer); + u.append_id(p_particles->frame_params_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(p_particles->particle_buffer); + u.append_id(p_particles->particle_buffer); uniforms.push_back(u); } @@ -4956,9 +4969,9 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; if (p_particles->emission_storage_buffer.is_valid()) { - u.ids.push_back(p_particles->emission_storage_buffer); + u.append_id(p_particles->emission_storage_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -4971,9 +4984,9 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt if (sub_emitter->emission_buffer == nullptr) { //no emission buffer, allocate emission buffer _particles_allocate_emission_buffer(sub_emitter); } - u.ids.push_back(sub_emitter->emission_storage_buffer); + u.append_id(sub_emitter->emission_storage_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -5244,7 +5257,7 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt if (rd_tex == RID()) { rd_tex = default_rd_textures[DEFAULT_RD_TEXTURE_3D_WHITE]; } - u.ids.push_back(rd_tex); + u.append_id(rd_tex); } uniforms.push_back(u); } @@ -5253,9 +5266,9 @@ void RendererStorageRD::_particles_process(Particles *p_particles, double p_delt u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.binding = 1; if (collision_heightmap_texture.is_valid()) { - u.ids.push_back(collision_heightmap_texture); + u.append_id(collision_heightmap_texture); } else { - u.ids.push_back(default_rd_textures[DEFAULT_RD_TEXTURE_BLACK]); + u.append_id(default_rd_textures[DEFAULT_RD_TEXTURE_BLACK]); } uniforms.push_back(u); } @@ -5389,7 +5402,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(particles->particles_sort_buffer); + u.append_id(particles->particles_sort_buffer); uniforms.push_back(u); } @@ -5420,6 +5433,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & copy_push_constant.frame_remainder = particles->interpolate ? particles->frame_remainder : 0.0; copy_push_constant.total_particles = particles->amount; + copy_push_constant.copy_mode_2d = false; Vector3 axis = -p_axis; // cameras look to z negative @@ -5440,7 +5454,7 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & if (do_sort) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_SORT_BUFFER]); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_SORT_BUFFER + particles->userdata_count * ParticlesShader::COPY_MODE_MAX]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->trail_bind_pose_uniform_set, 2); @@ -5455,7 +5469,10 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & copy_push_constant.total_particles *= copy_push_constant.total_particles; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[do_sort ? ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : (particles->mode == RS::PARTICLES_MODE_2D ? ParticlesShader::COPY_MODE_FILL_INSTANCES_2D : ParticlesShader::COPY_MODE_FILL_INSTANCES)]); + uint32_t copy_pipeline = do_sort ? ParticlesShader::COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER : ParticlesShader::COPY_MODE_FILL_INSTANCES; + copy_pipeline += particles->userdata_count * ParticlesShader::COPY_MODE_MAX; + copy_push_constant.copy_mode_2d = particles->mode == RS::PARTICLES_MODE_2D ? 1 : 0; + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[copy_pipeline]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0); if (do_sort) { RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_sort_uniform_set, 1); @@ -5470,6 +5487,19 @@ void RendererStorageRD::particles_set_view_axis(RID p_particles, const Vector3 & } void RendererStorageRD::_particles_update_buffers(Particles *particles) { + uint32_t userdata_count = 0; + + const Material *material = material_owner.get_or_null(particles->process_material); + if (material && material->shader && material->shader->data) { + const ParticlesShaderData *shader_data = static_cast<const ParticlesShaderData *>(material->shader->data); + userdata_count = shader_data->userdata_count; + } + + if (userdata_count != particles->userdata_count) { + // Mismatch userdata, re-create buffers. + _particles_free_data(particles); + } + if (particles->amount > 0 && particles->particle_buffer.is_null()) { int total_amount = particles->amount; if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) { @@ -5478,7 +5508,9 @@ void RendererStorageRD::_particles_update_buffers(Particles *particles) { uint32_t xform_size = particles->mode == RS::PARTICLES_MODE_2D ? 2 : 3; - particles->particle_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticleData) * total_amount); + particles->particle_buffer = RD::get_singleton()->storage_buffer_create((sizeof(ParticleData) + userdata_count * sizeof(float) * 4) * total_amount); + + particles->userdata_count = userdata_count; particles->particle_instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(float) * 4 * (xform_size + 1 + 1) * total_amount); //needs to clear it @@ -5490,14 +5522,14 @@ void RendererStorageRD::_particles_update_buffers(Particles *particles) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(particles->particle_buffer); + u.append_id(particles->particle_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(particles->particle_instance_buffer); + u.append_id(particles->particle_instance_buffer); uniforms.push_back(u); } @@ -5595,9 +5627,9 @@ void RendererStorageRD::update_particles() { u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; if (particles->trail_bind_pose_buffer.is_valid()) { - u.ids.push_back(particles->trail_bind_pose_buffer); + u.append_id(particles->trail_bind_pose_buffer); } else { - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); } uniforms.push_back(u); } @@ -5680,6 +5712,21 @@ void RendererStorageRD::update_particles() { total_amount *= particles->trail_bind_poses.size(); } + // Affect 2D only. + if (particles->use_local_coords) { + // In local mode, particle positions are calculated locally (relative to the node position) + // and they're also drawn locally. + // It works as expected, so we just pass an identity transform. + store_transform(Transform3D(), copy_push_constant.inv_emission_transform); + } else { + // In global mode, particle positions are calculated globally (relative to the canvas origin) + // but they're drawn locally. + // So, we need to pass the inverse of the emission transform to bring the + // particles to local coordinates before drawing. + Transform3D inv = particles->emission_transform.affine_inverse(); + store_transform(inv, copy_push_constant.inv_emission_transform); + } + copy_push_constant.total_particles = total_amount; copy_push_constant.frame_remainder = particles->interpolate ? particles->frame_remainder : 0.0; copy_push_constant.align_mode = particles->transform_align; @@ -5702,7 +5749,8 @@ void RendererStorageRD::update_particles() { copy_push_constant.lifetime_reverse = particles->draw_order == RS::PARTICLES_DRAW_ORDER_REVERSE_LIFETIME; RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[particles->mode == RS::PARTICLES_MODE_2D ? ParticlesShader::COPY_MODE_FILL_INSTANCES_2D : ParticlesShader::COPY_MODE_FILL_INSTANCES]); + copy_push_constant.copy_mode_2d = particles->mode == RS::PARTICLES_MODE_2D ? 1 : 0; + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, particles_shader.copy_pipelines[ParticlesShader::COPY_MODE_FILL_INSTANCES + particles->userdata_count * ParticlesShader::COPY_MODE_MAX]); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->particles_copy_uniform_set, 0); RD::get_singleton()->compute_list_bind_uniform_set(compute_list, particles->trail_bind_pose_uniform_set, 2); RD::get_singleton()->compute_list_set_push_constant(compute_list, ©_push_constant, sizeof(ParticlesShader::CopyPushConstant)); @@ -5754,6 +5802,12 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["COLLIDED"] = &uses_collision; + userdata_count = 0; + for (uint32_t i = 0; i < ParticlesShader::MAX_USERDATAS; i++) { + userdatas_used[i] = false; + actions.usage_flag_pointers["USERDATA" + itos(i + 1)] = &userdatas_used[i]; + } + actions.uniforms = &uniforms; Error err = base_singleton->particles_shader.compiler.compile(RS::SHADER_PARTICLES, code, &actions, path, gen_code); @@ -5763,6 +5817,12 @@ void RendererStorageRD::ParticlesShaderData::set_code(const String &p_code) { version = base_singleton->particles_shader.shader.version_create(); } + for (uint32_t i = 0; i < ParticlesShader::MAX_USERDATAS; i++) { + if (userdatas_used[i]) { + userdata_count++; + } + } + base_singleton->particles_shader.shader.version_set_compute_code(version, gen_code.code, gen_code.uniforms, gen_code.stage_globals[ShaderCompiler::STAGE_COMPUTE], gen_code.defines); ERR_FAIL_COND(!base_singleton->particles_shader.shader.version_is_valid(version)); @@ -6255,7 +6315,7 @@ void RendererStorageRD::skeleton_allocate_data(RID p_skeleton, int p_bones, bool RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(skeleton->buffer); + u.append_id(skeleton->buffer); uniforms.push_back(u); } skeleton->uniform_set_mi = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON); @@ -6495,12 +6555,6 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) { light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } -void RendererStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) { - Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND(!light); - light->shadow_color = p_color; -} - void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) { Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); @@ -6540,6 +6594,16 @@ void RendererStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT); } +void RendererStorageRD::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) { + Light *light = light_owner.get_or_null(p_light); + ERR_FAIL_COND(!light); + + light->distance_fade = p_enabled; + light->distance_fade_begin = p_begin; + light->distance_fade_shadow = p_shadow; + light->distance_fade_length = p_length; +} + void RendererStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { Light *light = light_owner.get_or_null(p_light); ERR_FAIL_COND(!light); @@ -7076,21 +7140,21 @@ void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 1; - u.ids.push_back(voxel_gi->octree_buffer); + u.append_id(voxel_gi->octree_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(voxel_gi->data_buffer); + u.append_id(voxel_gi->data_buffer); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(shared_tex); + u.append_id(shared_tex); uniforms.push_back(u); } @@ -7938,33 +8002,36 @@ void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 1; - u.ids.push_back(rt->sdf_buffer_write); + u.append_id(rt->sdf_buffer_write); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 2; - u.ids.push_back(rt->sdf_buffer_read); + u.append_id(rt->sdf_buffer_read); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 3; - u.ids.push_back(rt->sdf_buffer_process[0]); + u.append_id(rt->sdf_buffer_process[0]); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; u.binding = 4; - u.ids.push_back(rt->sdf_buffer_process[1]); + u.append_id(rt->sdf_buffer_process[1]); uniforms.push_back(u); } rt->sdf_buffer_process_uniform_sets[0] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0); - SWAP(uniforms.write[2].ids.write[0], uniforms.write[3].ids.write[0]); + RID aux2 = uniforms.write[2].get_id(0); + RID aux3 = uniforms.write[3].get_id(0); + uniforms.write[2].set_id(0, aux3); + uniforms.write[3].set_id(0, aux2); rt->sdf_buffer_process_uniform_sets[1] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0); } } @@ -9930,6 +9997,11 @@ RendererStorageRD::RendererStorageRD() { actions.renames["ACTIVE"] = "particle_active"; actions.renames["RESTART"] = "restart"; actions.renames["CUSTOM"] = "PARTICLE.custom"; + for (int i = 0; i < ParticlesShader::MAX_USERDATAS; i++) { + String udname = "USERDATA" + itos(i + 1); + actions.renames[udname] = "PARTICLE.userdata" + itos(i + 1); + actions.usage_defines[udname] = "#define USERDATA" + itos(i + 1) + "_USED\n"; + } actions.renames["TRANSFORM"] = "PARTICLE.xform"; actions.renames["TIME"] = "frame_history.data[0].time"; actions.renames["PI"] = _MKSTR(Math_PI); @@ -9999,11 +10071,9 @@ void process() { Vector<RD::Uniform> uniforms; { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_SAMPLER; - u.binding = 1; - u.ids.resize(12); - RID *ids_ptr = u.ids.ptrw(); + Vector<RID> ids; + ids.resize(12); + RID *ids_ptr = ids.ptrw(); ids_ptr[0] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[1] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); ids_ptr[2] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); @@ -10016,6 +10086,8 @@ void process() { ids_ptr[9] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[10] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); ids_ptr[11] = sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED); + + RD::Uniform u(RD::UNIFORM_TYPE_SAMPLER, 1, ids); uniforms.push_back(u); } @@ -10023,7 +10095,7 @@ void process() { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 2; - u.ids.push_back(global_variables_get_storage_buffer()); + u.append_id(global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -10034,17 +10106,26 @@ void process() { { Vector<String> copy_modes; - copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n"); - copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define MODE_2D\n"); - copy_modes.push_back("\n#define MODE_FILL_SORT_BUFFER\n#define USE_SORT_BUFFER\n"); - copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define USE_SORT_BUFFER\n"); + for (int i = 0; i <= ParticlesShader::MAX_USERDATAS; i++) { + if (i == 0) { + copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n"); + copy_modes.push_back("\n#define MODE_FILL_SORT_BUFFER\n#define USE_SORT_BUFFER\n"); + copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define USE_SORT_BUFFER\n"); + } else { + copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define USERDATA_COUNT " + itos(i) + "\n"); + copy_modes.push_back("\n#define MODE_FILL_SORT_BUFFER\n#define USE_SORT_BUFFER\n#define USERDATA_COUNT " + itos(i) + "\n"); + copy_modes.push_back("\n#define MODE_FILL_INSTANCES\n#define USE_SORT_BUFFER\n#define USERDATA_COUNT " + itos(i) + "\n"); + } + } particles_shader.copy_shader.initialize(copy_modes); particles_shader.copy_shader_version = particles_shader.copy_shader.version_create(); - for (int i = 0; i < ParticlesShader::COPY_MODE_MAX; i++) { - particles_shader.copy_pipelines[i] = RD::get_singleton()->compute_pipeline_create(particles_shader.copy_shader.version_get_shader(particles_shader.copy_shader_version, i)); + for (int i = 0; i <= ParticlesShader::MAX_USERDATAS; i++) { + for (int j = 0; j < ParticlesShader::COPY_MODE_MAX; j++) { + particles_shader.copy_pipelines[i * ParticlesShader::COPY_MODE_MAX + j] = RD::get_singleton()->compute_pipeline_create(particles_shader.copy_shader.version_get_shader(particles_shader.copy_shader_version, i * ParticlesShader::COPY_MODE_MAX + j)); + } } } @@ -10083,7 +10164,7 @@ void process() { RD::Uniform u; u.binding = 0; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.ids.push_back(default_rd_storage_buffer); + u.append_id(default_rd_storage_buffer); uniforms.push_back(u); } skeleton_shader.default_skeleton_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, skeleton_shader.version_shader[0], SkeletonShader::UNIFORM_SET_SKELETON); diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h index 6febb71e93..9416d04cdd 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.h +++ b/servers/rendering/renderer_rd/renderer_storage_rd.h @@ -751,6 +751,8 @@ private: RID particle_instance_buffer; RID frame_params_buffer; + uint32_t userdata_count = 0; + RID particles_material_uniform_set; RID particles_copy_uniform_set; RID particles_transforms_buffer_uniform_set; @@ -849,12 +851,16 @@ private: uint32_t order_by_lifetime; uint32_t lifetime_split; uint32_t lifetime_reverse; - uint32_t pad; + uint32_t copy_mode_2d; + + float inv_emission_transform[16]; }; enum { + MAX_USERDATAS = 6 + }; + enum { COPY_MODE_FILL_INSTANCES, - COPY_MODE_FILL_INSTANCES_2D, COPY_MODE_FILL_SORT_BUFFER, COPY_MODE_FILL_INSTANCES_WITH_SORT_BUFFER, COPY_MODE_MAX, @@ -862,7 +868,7 @@ private: ParticlesCopyShaderRD copy_shader; RID copy_shader_version; - RID copy_pipelines[COPY_MODE_MAX]; + RID copy_pipelines[COPY_MODE_MAX * (MAX_USERDATAS + 1)]; LocalVector<float> pose_update_buffer; @@ -888,7 +894,10 @@ private: RID pipeline; - bool uses_time; + bool uses_time = false; + + bool userdatas_used[ParticlesShader::MAX_USERDATAS] = {}; + uint32_t userdata_count = 0; virtual void set_code(const String &p_Code); virtual void set_default_texture_param(const StringName &p_name, RID p_texture, int p_index); @@ -1016,7 +1025,6 @@ private: RS::LightType type; float param[RS::LIGHT_PARAM_MAX]; Color color = Color(1, 1, 1, 1); - Color shadow_color; RID projector; bool shadow = false; bool negative = false; @@ -1024,6 +1032,10 @@ private: RS::LightBakeMode bake_mode = RS::LIGHT_BAKE_DYNAMIC; uint32_t max_sdfgi_cascade = 2; uint32_t cull_mask = 0xFFFFFFFF; + bool distance_fade = false; + real_t distance_fade_begin = 40.0; + real_t distance_fade_shadow = 50.0; + real_t distance_fade_length = 10.0; RS::LightOmniShadowMode omni_shadow_mode = RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; RS::LightDirectionalShadowMode directional_shadow_mode = RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL; bool directional_blend_splits = false; @@ -1752,7 +1764,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(multimesh->buffer); + u.append_id(multimesh->buffer); uniforms.push_back(u); multimesh->uniform_set_3d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); } @@ -1767,7 +1779,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(multimesh->buffer); + u.append_id(multimesh->buffer); uniforms.push_back(u); multimesh->uniform_set_2d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); } @@ -1805,7 +1817,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(skeleton->buffer); + u.append_id(skeleton->buffer); uniforms.push_back(u); skeleton->uniform_set_3d = RD::get_singleton()->uniform_set_create(uniforms, p_shader, p_set); } @@ -1828,10 +1840,10 @@ public: void light_set_color(RID p_light, const Color &p_color); void light_set_param(RID p_light, RS::LightParam p_param, float p_value); void light_set_shadow(RID p_light, bool p_enabled); - void light_set_shadow_color(RID p_light, const Color &p_color); void light_set_projector(RID p_light, RID p_texture); void light_set_negative(RID p_light, bool p_enable); void light_set_cull_mask(RID p_light, uint32_t p_mask); + void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length); void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode); void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade); @@ -1876,18 +1888,31 @@ public: return light->color; } - _FORCE_INLINE_ Color light_get_shadow_color(RID p_light) { + _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, Color()); + ERR_FAIL_COND_V(!light, 0); - return light->shadow_color; + return light->cull_mask; } - _FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) { + _FORCE_INLINE_ bool light_is_distance_fade_enabled(RID p_light) { const Light *light = light_owner.get_or_null(p_light); - ERR_FAIL_COND_V(!light, 0); + return light->distance_fade; + } - return light->cull_mask; + _FORCE_INLINE_ float light_get_distance_fade_begin(RID p_light) { + const Light *light = light_owner.get_or_null(p_light); + return light->distance_fade_begin; + } + + _FORCE_INLINE_ float light_get_distance_fade_shadow(RID p_light) { + const Light *light = light_owner.get_or_null(p_light); + return light->distance_fade_shadow; + } + + _FORCE_INLINE_ float light_get_distance_fade_length(RID p_light) { + const Light *light = light_owner.get_or_null(p_light); + return light->distance_fade_length; } _FORCE_INLINE_ bool light_has_shadow(RID p_light) const { @@ -2162,6 +2187,8 @@ public: void particles_set_speed_scale(RID p_particles, double p_scale); void particles_set_use_local_coordinates(RID p_particles, bool p_enable); void particles_set_process_material(RID p_particles, RID p_material); + RID particles_get_process_material(RID p_particles) const; + void particles_set_fixed_fps(RID p_particles, int p_fps); void particles_set_interpolate(RID p_particles, bool p_enable); void particles_set_fractional_delta(RID p_particles, bool p_enable); @@ -2240,7 +2267,7 @@ public: RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.binding = 0; - u.ids.push_back(particles->particle_instance_buffer); + u.append_id(particles->particle_instance_buffer); uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/shaders/blit.glsl b/servers/rendering/renderer_rd/shaders/blit.glsl index 8051f96738..14f190a49f 100644 --- a/servers/rendering/renderer_rd/shaders/blit.glsl +++ b/servers/rendering/renderer_rd/shaders/blit.glsl @@ -4,7 +4,7 @@ #VERSION_DEFINES -layout(push_constant, binding = 0, std140) uniform Pos { +layout(push_constant, std140) uniform Pos { vec4 src_rect; vec4 dst_rect; @@ -34,7 +34,7 @@ void main() { #VERSION_DEFINES -layout(push_constant, binding = 0, std140) uniform Pos { +layout(push_constant, std140) uniform Pos { vec4 src_rect; vec4 dst_rect; diff --git a/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl index 52bf2886b5..e7a2e18323 100644 --- a/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl @@ -2,7 +2,7 @@ #define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 1) #define FLAG_GLOW_FIRST_PASS (1 << 2) -layout(push_constant, binding = 1, std430) uniform Blur { +layout(push_constant, std430) uniform Blur { vec2 pixel_size; uint flags; uint pad; diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl index fadea1631c..b90a527554 100644 --- a/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl @@ -1,4 +1,4 @@ -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 size; float z_far; float z_near; diff --git a/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl index 9f89f4b3b7..930cf792cb 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl @@ -6,7 +6,7 @@ layout(location = 0) in highp vec3 vertex; -layout(push_constant, binding = 0, std430) uniform Constants { +layout(push_constant, std430) uniform Constants { mat4 projection; mat2x4 modelview; vec2 direction; @@ -34,7 +34,7 @@ void main() { #VERSION_DEFINES -layout(push_constant, binding = 0, std430) uniform Constants { +layout(push_constant, std430) uniform Constants { mat4 projection; mat2x4 modelview; vec2 direction; diff --git a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl index 2bdfbabfcf..0fafc7d486 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_sdf.glsl @@ -12,7 +12,7 @@ layout(r16_snorm, set = 0, binding = 2) uniform restrict writeonly image2D dst_s layout(rg16i, set = 0, binding = 3) uniform restrict readonly iimage2D src_process; layout(rg16i, set = 0, binding = 4) uniform restrict writeonly iimage2D dst_process; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 size; int stride; int shift; diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index 0cff505cae..12f57b0178 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -41,7 +41,7 @@ // Push Constant -layout(push_constant, binding = 0, std430) uniform DrawData { +layout(push_constant, std430) uniform DrawData { vec2 world_x; vec2 world_y; vec2 world_ofs; diff --git a/servers/rendering/renderer_rd/shaders/cluster_debug.glsl b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl index 40da2c6e5c..0034de8c91 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_debug.glsl @@ -40,7 +40,7 @@ const vec3 usage_gradient[33] = vec3[]( // 1 (none) + 32 vec3(0.83, 0.22, 0.27), vec3(0.83, 0.22, 0.32), vec3(1.00, 0.63, 0.70)); -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { uvec2 screen_size; uvec2 cluster_screen_size; diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl index 6d95722a57..2fe230f0bf 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl @@ -9,7 +9,7 @@ layout(location = 0) in vec3 vertex_attrib; layout(location = 0) out float depth_interp; layout(location = 1) out flat uint element_index; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { uint base_index; uint pad0; uint pad1; diff --git a/servers/rendering/renderer_rd/shaders/cluster_store.glsl b/servers/rendering/renderer_rd/shaders/cluster_store.glsl index b0606efa94..64a145f3c6 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_store.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_store.glsl @@ -6,7 +6,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { uint cluster_render_data_size; // how much data for a single cluster takes uint max_render_element_count_div_32; //divided by 32 uvec2 cluster_screen_size; diff --git a/servers/rendering/renderer_rd/shaders/copy.glsl b/servers/rendering/renderer_rd/shaders/copy.glsl index ecf7bb9817..4563ac7af9 100644 --- a/servers/rendering/renderer_rd/shaders/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/copy.glsl @@ -17,7 +17,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #define FLAG_HIGH_QUALITY_GLOW (1 << 8) #define FLAG_ALPHA_TO_ONE (1 << 9) -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec4 section; ivec2 target; uint flags; diff --git a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl index 8c68e2dc2f..9787c9879d 100644 --- a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl @@ -4,9 +4,22 @@ #VERSION_DEFINES +#ifdef MULTIVIEW +#ifdef has_VK_KHR_multiview +#extension GL_EXT_multiview : enable +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#endif //MULTIVIEW + +#ifdef MULTIVIEW +layout(location = 0) out vec3 uv_interp; +#else layout(location = 0) out vec2 uv_interp; +#endif -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec4 section; vec2 pixel_size; bool flip_y; @@ -19,9 +32,11 @@ params; void main() { vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); - uv_interp = base_arr[gl_VertexIndex]; - - vec2 vpos = uv_interp; + uv_interp.xy = base_arr[gl_VertexIndex]; +#ifdef MULTIVIEW + uv_interp.z = ViewIndex; +#endif + vec2 vpos = uv_interp.xy; if (params.use_section) { vpos = params.section.xy + vpos * params.section.zw; } @@ -39,7 +54,16 @@ void main() { #VERSION_DEFINES -layout(push_constant, binding = 1, std430) uniform Params { +#ifdef MULTIVIEW +#ifdef has_VK_KHR_multiview +#extension GL_EXT_multiview : enable +#define ViewIndex gl_ViewIndex +#else // has_VK_KHR_multiview +#define ViewIndex 0 +#endif // has_VK_KHR_multiview +#endif //MULTIVIEW + +layout(push_constant, std430) uniform Params { vec4 section; vec2 pixel_size; bool flip_y; @@ -52,12 +76,25 @@ layout(push_constant, binding = 1, std430) uniform Params { } params; +#ifdef MULTIVIEW +layout(location = 0) in vec3 uv_interp; +#else layout(location = 0) in vec2 uv_interp; +#endif +#ifdef MULTIVIEW +layout(set = 0, binding = 0) uniform sampler2DArray source_color; +#ifdef MODE_TWO_SOURCES +layout(set = 1, binding = 0) uniform sampler2DArray source_depth; +layout(location = 1) out float depth; +#endif /* MODE_TWO_SOURCES */ +#else layout(set = 0, binding = 0) uniform sampler2D source_color; #ifdef MODE_TWO_SOURCES layout(set = 1, binding = 0) uniform sampler2D source_color2; -#endif +#endif /* MODE_TWO_SOURCES */ +#endif /* MULTIVIEW */ + layout(location = 0) out vec4 frag_color; vec3 linear_to_srgb(vec3 color) { @@ -68,9 +105,14 @@ vec3 linear_to_srgb(vec3 color) { } void main() { +#ifdef MULTIVIEW + vec3 uv = uv_interp; +#else vec2 uv = uv_interp; +#endif #ifdef MODE_PANORAMA_TO_DP + // Note, multiview and panorama should not be mixed at this time //obtain normal from dual paraboloid uv #define M_PI 3.14159265359 @@ -98,10 +140,20 @@ void main() { uv = 1.0 - uv; } #endif + +#ifdef MULTIVIEW + vec4 color = textureLod(source_color, uv, 0.0); +#ifdef MODE_TWO_SOURCES + // In multiview our 2nd input will be our depth map + depth = textureLod(source_depth, uv, 0.0).r; +#endif /* MODE_TWO_SOURCES */ + +#else vec4 color = textureLod(source_color, uv, 0.0); #ifdef MODE_TWO_SOURCES color += textureLod(source_color2, uv, 0.0); -#endif +#endif /* MODE_TWO_SOURCES */ +#endif /* MULTIVIEW */ if (params.force_luminance) { color.rgb = vec3(max(max(color.r, color.g), color.b)); } diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl index 69b895ed29..e77d0de719 100644 --- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl @@ -4,7 +4,7 @@ #VERSION_DEFINES -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { float z_far; float z_near; vec2 texel_size; @@ -31,7 +31,7 @@ layout(location = 0) in vec2 uv_interp; layout(set = 0, binding = 0) uniform samplerCube source_cube; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { float z_far; float z_near; vec2 texel_size; diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl b/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl index b329e67293..641e0906f5 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl @@ -1,4 +1,4 @@ -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { uint face_size; uint face_id; // only used in raster shader } diff --git a/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl b/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl index 324d306218..0990dc7c2f 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl @@ -25,7 +25,7 @@ #VERSION_DEFINES -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { int mip_level; uint face_id; } @@ -47,7 +47,7 @@ void main() { #VERSION_DEFINES -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { int mip_level; uint face_id; } diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl index 28f4dc59ec..1d46f59408 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl @@ -21,24 +21,38 @@ void main() { vec2 uv = ((vec2(id.xy) * 2.0 + 1.0) / (params.face_size) - 1.0); vec3 N = texelCoordToVec(uv, id.z); - //vec4 color = color_interp; - if (params.use_direct_write) { imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0)); } else { vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); + float solid_angle_texel = 4.0 * M_PI / (6.0 * params.face_size * params.face_size); + float roughness2 = params.roughness * params.roughness; + float roughness4 = roughness2 * roughness2; + vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + mat3 T; + T[0] = normalize(cross(UpVector, N)); + T[1] = cross(N, T[0]); + T[2] = N; + for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) { vec2 xi = Hammersley(sampleNum, params.sample_count); - vec3 H = ImportanceSampleGGX(xi, params.roughness, N); - vec3 V = N; - vec3 L = (2.0 * dot(V, H) * H - V); + vec3 H = T * ImportanceSampleGGX(xi, roughness4); + float NdotH = dot(N, H); + vec3 L = (2.0 * NdotH * H - N); float ndotl = clamp(dot(N, L), 0.0, 1.0); if (ndotl > 0.0) { - sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl; + float D = DistributionGGX(NdotH, roughness4); + float pdf = D * NdotH / (4.0 * NdotH) + 0.0001; + + float solid_angle_sample = 1.0 / (float(params.sample_count) * pdf + 0.0001); + + float mipLevel = params.roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel); + + sum.rgb += textureLod(source_cube, L, mipLevel).rgb * ndotl; sum.a += ndotl; } } diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl index be12be5dec..1bee428a6f 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl @@ -1,6 +1,6 @@ #define M_PI 3.14159265359 -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { uint face_id; uint sample_count; float roughness; @@ -47,12 +47,10 @@ vec3 texelCoordToVec(vec2 uv, uint faceID) { return normalize(result); } -vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) { - float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph] - +vec3 ImportanceSampleGGX(vec2 xi, float roughness4) { // Compute distribution direction - float Phi = 2.0 * M_PI * Xi.x; - float CosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a * a - 1.0) * Xi.y)); + float Phi = 2.0 * M_PI * xi.x; + float CosTheta = sqrt((1.0 - xi.y) / (1.0 + (roughness4 - 1.0) * xi.y)); float SinTheta = sqrt(1.0 - CosTheta * CosTheta); // Convert to spherical direction @@ -61,12 +59,15 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) { H.y = SinTheta * sin(Phi); H.z = CosTheta; - vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); - vec3 TangentX = normalize(cross(UpVector, N)); - vec3 TangentY = cross(N, TangentX); + return H; +} + +float DistributionGGX(float NdotH, float roughness4) { + float NdotH2 = NdotH * NdotH; + float denom = (NdotH2 * (roughness4 - 1.0) + 1.0); + denom = M_PI * denom * denom; - // Tangent to world space - return TangentX * H.x + TangentY * H.y + N * H.z; + return roughness4 / denom; } // https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl index 2570308816..c29accd8a7 100644 --- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl @@ -42,17 +42,33 @@ void main() { } else { vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); + float solid_angle_texel = 4.0 * M_PI / (6.0 * params.face_size * params.face_size); + float roughness2 = params.roughness * params.roughness; + float roughness4 = roughness2 * roughness2; + vec3 UpVector = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0); + mat3 T; + T[0] = normalize(cross(UpVector, N)); + T[1] = cross(N, T[0]); + T[2] = N; + for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) { vec2 xi = Hammersley(sampleNum, params.sample_count); - vec3 H = ImportanceSampleGGX(xi, params.roughness, N); - vec3 V = N; - vec3 L = (2.0 * dot(V, H) * H - V); + vec3 H = T * ImportanceSampleGGX(xi, roughness4); + float NdotH = dot(N, H); + vec3 L = (2.0 * NdotH * H - N); float ndotl = clamp(dot(N, L), 0.0, 1.0); if (ndotl > 0.0) { - sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl; + float D = DistributionGGX(NdotH, roughness4); + float pdf = D * NdotH / (4.0 * NdotH) + 0.0001; + + float solid_angle_sample = 1.0 / (float(params.sample_count) * pdf + 0.0001); + + float mipLevel = params.roughness == 0.0 ? 0.0 : 0.5 * log2(solid_angle_sample / solid_angle_texel); + + sum.rgb += textureLod(source_cube, L, mipLevel).rgb * ndotl; sum.a += ndotl; } } diff --git a/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl b/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl index 54a7790f77..c8eb78a2f0 100644 --- a/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl +++ b/servers/rendering/renderer_rd/shaders/fsr_upscale.glsl @@ -53,7 +53,7 @@ layout(set = 0, binding = 0) uniform sampler2D source_image; #define FSR_UPSCALE_PASS_TYPE_EASU 0 #define FSR_UPSCALE_PASS_TYPE_RCAS 1 -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { float resolution_width; float resolution_height; float upscaled_width; diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl index 9854f124d7..0c7f08813b 100644 --- a/servers/rendering/renderer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/gi.glsl @@ -86,7 +86,7 @@ voxel_gi_instances; layout(set = 0, binding = 17) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES]; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 screen_size; float z_near; float z_far; diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl index a6d65bffeb..6c73864bf6 100644 --- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl +++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl @@ -58,7 +58,7 @@ lights; #endif -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec3 limits; uint stack_size; diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 52787bb204..61c8488a05 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -76,10 +76,6 @@ struct DirectionalLightData { highp mat4 shadow_matrix2; highp mat4 shadow_matrix3; highp mat4 shadow_matrix4; - mediump vec4 shadow_color1; - mediump vec4 shadow_color2; - mediump vec4 shadow_color3; - mediump vec4 shadow_color4; highp vec2 uv_scale1; highp vec2 uv_scale2; highp vec2 uv_scale3; diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl index 466442b67a..0ee4cf6e31 100644 --- a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl +++ b/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl @@ -28,7 +28,7 @@ layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_lumin layout(set = 2, binding = 0) uniform sampler2D prev_luminance; #endif -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 source_size; float max_luminance; float min_luminance; diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl index 3cde9923fa..b8860f6518 100644 --- a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl @@ -1,5 +1,5 @@ -layout(push_constant, binding = 1, std430) uniform PushConstant { +layout(push_constant, std430) uniform PushConstant { ivec2 source_size; ivec2 dest_size; diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index 328becbc20..1b1051ecfa 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -112,6 +112,24 @@ struct ParticleData { uint flags; vec4 color; vec4 custom; +#ifdef USERDATA1_USED + vec4 userdata1; +#endif +#ifdef USERDATA2_USED + vec4 userdata2; +#endif +#ifdef USERDATA3_USED + vec4 userdata3; +#endif +#ifdef USERDATA4_USED + vec4 userdata4; +#endif +#ifdef USERDATA5_USED + vec4 userdata5; +#endif +#ifdef USERDATA6_USED + vec4 userdata6; +#endif }; layout(set = 1, binding = 1, std430) restrict buffer Particles { @@ -168,7 +186,7 @@ layout(set = 3, binding = 0, std140) uniform MaterialUniforms{ } material; #endif -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { float lifetime; bool clear; uint total_particles; diff --git a/servers/rendering/renderer_rd/shaders/particles_copy.glsl b/servers/rendering/renderer_rd/shaders/particles_copy.glsl index e88e68b511..afbd5a9caa 100644 --- a/servers/rendering/renderer_rd/shaders/particles_copy.glsl +++ b/servers/rendering/renderer_rd/shaders/particles_copy.glsl @@ -16,6 +16,9 @@ struct ParticleData { uint flags; vec4 color; vec4 custom; +#ifdef USERDATA_COUNT + vec4 userdata[USERDATA_COUNT]; +#endif }; layout(set = 0, binding = 1, std430) restrict readonly buffer Particles { @@ -42,7 +45,7 @@ layout(set = 2, binding = 0, std430) restrict readonly buffer TrailBindPoses { } trail_bind_poses; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec3 sort_direction; uint total_particles; @@ -57,7 +60,9 @@ layout(push_constant, binding = 0, std430) uniform Params { bool order_by_lifetime; uint lifetime_split; bool lifetime_reverse; - uint pad; + bool copy_mode_2d; + + mat4 inv_emission_transform; } params; @@ -196,30 +201,33 @@ void main() { txform = txform * trail_bind_poses.data[part_ofs]; } + if (params.copy_mode_2d) { + // In global mode, bring 2D particles to local coordinates + // as they will be drawn with the node position as origin. + txform = params.inv_emission_transform * txform; + } + txform = transpose(txform); } else { txform = mat4(vec4(0.0), vec4(0.0), vec4(0.0), vec4(0.0)); //zero scale, becomes invisible } -#ifdef MODE_2D - - uint write_offset = gl_GlobalInvocationID.x * (2 + 1 + 1); //xform + color + custom + if (params.copy_mode_2d) { + uint write_offset = gl_GlobalInvocationID.x * (2 + 1 + 1); //xform + color + custom - instances.data[write_offset + 0] = txform[0]; - instances.data[write_offset + 1] = txform[1]; - instances.data[write_offset + 2] = particles.data[particle].color; - instances.data[write_offset + 3] = particles.data[particle].custom; - -#else - - uint write_offset = gl_GlobalInvocationID.x * (3 + 1 + 1); //xform + color + custom + instances.data[write_offset + 0] = txform[0]; + instances.data[write_offset + 1] = txform[1]; + instances.data[write_offset + 2] = particles.data[particle].color; + instances.data[write_offset + 3] = particles.data[particle].custom; + } else { + uint write_offset = gl_GlobalInvocationID.x * (3 + 1 + 1); //xform + color + custom - instances.data[write_offset + 0] = txform[0]; - instances.data[write_offset + 1] = txform[1]; - instances.data[write_offset + 2] = txform[2]; - instances.data[write_offset + 3] = particles.data[particle].color; - instances.data[write_offset + 4] = particles.data[particle].custom; -#endif //MODE_2D + instances.data[write_offset + 0] = txform[0]; + instances.data[write_offset + 1] = txform[1]; + instances.data[write_offset + 2] = txform[2]; + instances.data[write_offset + 3] = particles.data[particle].color; + instances.data[write_offset + 4] = particles.data[particle].custom; + } #endif } diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl index fecf812a8c..0e086331c0 100644 --- a/servers/rendering/renderer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/resolve.glsl @@ -25,7 +25,7 @@ layout(rg8ui, set = 3, binding = 0) uniform restrict writeonly uimage2D dest_vox #endif -layout(push_constant, binding = 16, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 screen_size; int sample_count; uint pad; diff --git a/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl index 7b964675ca..59027df8e9 100644 --- a/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl +++ b/servers/rendering/renderer_rd/shaders/roughness_limiter.glsl @@ -9,7 +9,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; layout(set = 0, binding = 0) uniform sampler2D source_normal; layout(r8, set = 1, binding = 0) uniform restrict writeonly image2D dest_roughness; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 screen_size; float curve; uint pad; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 97f7e0a6e6..a8648fc96a 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -478,8 +478,8 @@ layout(location = 0) out vec4 frag_color; #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) -/* Make a default specular mode SPECULAR_SCHLICK_GGX. */ -#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) && !defined(SPECULAR_PHONG) && !defined(SPECULAR_TOON) +// Default to SPECULAR_SCHLICK_GGX. +#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) #define SPECULAR_SCHLICK_GGX #endif @@ -552,7 +552,6 @@ void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, uint item_min_max = cluster_buffer.data[p_offset]; item_min = item_min_max & 0xFFFF; item_max = item_min_max >> 16; - ; item_from = item_min >> 5; item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements @@ -590,7 +589,7 @@ void main() { float rim = 0.0; float rim_tint = 0.0; float clearcoat = 0.0; - float clearcoat_gloss = 0.0; + float clearcoat_roughness = 0.0; float anisotropy = 0.0; vec2 anisotropy_flow = vec2(1.0, 0.0); vec4 fog = vec4(0.0); @@ -913,7 +912,17 @@ void main() { #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) if (scene_data.use_reflection_cubemap) { +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); + vec3 ref_vec = reflect(-view, bent_normal); +#else vec3 ref_vec = reflect(-view, normal); +#endif + float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -955,6 +964,36 @@ void main() { #if defined(CUSTOM_IRRADIANCE_USED) ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); #endif + +#ifdef LIGHT_CLEARCOAT_USED + + if (scene_data.use_reflection_cubemap) { + vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map + float NoV = max(dot(n, view), 0.0001); + vec3 ref_vec = reflect(-view, n); + // The clear coat layer assumes an IOR of 1.5 (4% reflectance) + float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV)); + float attenuation = 1.0 - Fc; + ambient_light *= attenuation; + specular_light *= attenuation; + + float horizon = min(1.0 + dot(ref_vec, normal), 1.0); + ref_vec = scene_data.radiance_inverse_xform * ref_vec; + float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; +#ifdef USE_RADIANCE_CUBEMAP_ARRAY + + float lod, blend; + blend = modf(roughness_lod, lod); + vec3 clearcoat_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; + clearcoat_light = mix(clearcoat_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); + +#else + vec3 clearcoat_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness_lod).rgb; + +#endif //USE_RADIANCE_CUBEMAP_ARRAY + specular_light += clearcoat_light * horizon * horizon * Fc * scene_data.ambient_light_color_energy.a; + } +#endif #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) //radiance @@ -1203,8 +1242,16 @@ void main() { if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) { continue; //not masked } - - reflection_process(reflection_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); +#else + vec3 bent_normal = normal; +#endif + reflection_process(reflection_index, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } } @@ -1556,10 +1603,11 @@ void main() { rim, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - binormal, tangent, anisotropy, + binormal, + tangent, anisotropy, #endif diffuse_light, specular_light); @@ -1627,7 +1675,7 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED tangent, binormal, anisotropy, @@ -1699,10 +1747,11 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, + binormal, anisotropy, #endif diffuse_light, specular_light); } @@ -1905,7 +1954,7 @@ void main() { frag_color = vec4(albedo, alpha); #else frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha); - //frag_color = vec4(1.0); +//frag_color = vec4(1.0); #endif //USE_NO_SHADING // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. 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 0f7cd18534..3b110aded2 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl @@ -15,13 +15,13 @@ #include "cluster_data_inc.glsl" #include "decal_data_inc.glsl" -#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) +#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #ifndef NORMAL_USED #define NORMAL_USED #endif #endif -layout(push_constant, binding = 0, std430) uniform DrawCall { +layout(push_constant, std430) uniform DrawCall { uint instance_index; uint uv_offset; uint pad0; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index d22f936a35..1c9b08b6d3 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -1,55 +1,29 @@ // Functions related to lighting -// This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V. -// We're dividing this factor off because the overall term we'll end up looks like -// (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012): -// -// F(L.V) D(N.H) G(N.L) G(N.V) / (4 N.L N.V) -// -// We're basically regouping this as -// -// F(L.V) D(N.H) [G(N.L)/(2 N.L)] [G(N.V) / (2 N.V)] -// -// and thus, this function implements the [G(N.m)/(2 N.m)] part with m = L or V. -// -// The contents of the D and G (G1) functions (GGX) are taken from -// E. Heitz, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", J. Comp. Graph. Tech. 3 (2) (2014). -// Eqns 71-72 and 85-86 (see also Eqns 43 and 80). - -float G_GGX_2cos(float cos_theta_m, float alpha) { - // Schlick's approximation - // C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994) - // Eq. (19), although see Heitz (2014) the about the problems with his derivation. - // It nevertheless approximates GGX well with k = alpha/2. - float k = 0.5 * alpha; - return 0.5 / (cos_theta_m * (1.0 - k) + k); - - // float cos2 = cos_theta_m * cos_theta_m; - // float sin2 = (1.0 - cos2); - // return 1.0 / (cos_theta_m + sqrt(cos2 + alpha * alpha * sin2)); -} - float D_GGX(float cos_theta_m, float alpha) { float alpha2 = alpha * alpha; float d = 1.0 + (alpha2 - 1.0) * cos_theta_m * cos_theta_m; return alpha2 / (M_PI * d * d); } -float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { - float cos2 = cos_theta_m * cos_theta_m; - float sin2 = (1.0 - cos2); - float s_x = alpha_x * cos_phi; - float s_y = alpha_y * sin_phi; - return 1.0 / max(cos_theta_m + sqrt(cos2 + (s_x * s_x + s_y * s_y) * sin2), 0.001); +// From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX +float V_GGX(float NdotL, float NdotV, float alpha) { + return 0.5 / mix(2.0 * NdotL * NdotV, NdotL + NdotV, alpha); } float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) { - float cos2 = cos_theta_m * cos_theta_m; - float sin2 = (1.0 - cos2); - float r_x = cos_phi / alpha_x; - float r_y = sin_phi / alpha_y; - float d = cos2 + sin2 * (r_x * r_x + r_y * r_y); - return 1.0 / max(M_PI * alpha_x * alpha_y * d * d, 0.001); + float alpha2 = alpha_x * alpha_y; + highp vec3 v = vec3(alpha_y * cos_phi, alpha_x * sin_phi, alpha2 * cos_theta_m); + highp float v2 = dot(v, v); + float w2 = alpha2 / v2; + float D = alpha2 * w2 * w2 * (1.0 / M_PI); + return D; +} + +float V_GGX_anisotropic(float alpha_x, float alpha_y, float TdotV, float TdotL, float BdotV, float BdotL, float NdotV, float NdotL) { + float Lambda_V = NdotL * length(vec3(alpha_x * TdotV, alpha_y * BdotV, NdotV)); + float Lambda_L = NdotV * length(vec3(alpha_x * TdotL, alpha_y * BdotL, NdotL)); + return 0.5 / (Lambda_V + Lambda_L); } float SchlickFresnel(float u) { @@ -58,14 +32,6 @@ float SchlickFresnel(float u) { return m2 * m2 * m; // pow(m,5) } -float GTR1(float NdotH, float a) { - if (a >= 1.0) - return 1.0 / M_PI; - float a2 = a * a; - float t = 1.0 + (a2 - 1.0) * NdotH * NdotH; - return (a2 - 1.0) / (M_PI * log(a2) * t); -} - vec3 F0(float metallic, float specular, vec3 albedo) { float dielectric = 0.16 * specular * specular; // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; @@ -87,7 +53,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float rim, float rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, + float clearcoat, float clearcoat_roughness, vec3 vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED vec3 B, vec3 T, float anisotropy, @@ -113,13 +79,13 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float NdotL = min(A + dot(N, L), 1.0); float cNdotL = max(NdotL, 0.0); // clamped NdotL float NdotV = dot(N, V); - float cNdotV = max(NdotV, 0.0); + float cNdotV = max(NdotV, 1e-4); -#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) +#if defined(DIFFUSE_BURLEY) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) vec3 H = normalize(V + L); #endif -#if defined(SPECULAR_BLINN) || defined(SPECULAR_SCHLICK_GGX) || defined(LIGHT_CLEARCOAT_USED) +#if defined(SPECULAR_SCHLICK_GGX) float cNdotH = clamp(A + dot(N, H), 0.0, 1.0); #endif @@ -203,26 +169,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte // D -#if defined(SPECULAR_BLINN) - - //normalized blinn - float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; - float blinn = pow(cNdotH, shininess); - blinn *= (shininess + 2.0) * (1.0 / (8.0 * M_PI)); - - specular_light += light_color * attenuation * specular_amount * blinn * f0 * orms_unpacked.w; - -#elif defined(SPECULAR_PHONG) - - vec3 R = normalize(-reflect(L, N)); - float cRdotV = clamp(A + dot(R, V), 0.0, 1.0); - float shininess = exp2(15.0 * (1.0 - roughness) + 1.0) * 0.25; - float phong = pow(cRdotV, shininess); - phong *= (shininess + 1.0) * (1.0 / (8.0 * M_PI)); - - specular_light += light_color * attenuation * specular_amount * phong * f0 * orms_unpacked.w; - -#elif defined(SPECULAR_TOON) +#if defined(SPECULAR_TOON) vec3 R = normalize(-reflect(L, N)); float RdotV = dot(R, V); @@ -236,24 +183,21 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #elif defined(SPECULAR_SCHLICK_GGX) // shlick+ggx as default - + float alpha_ggx = roughness * roughness; #if defined(LIGHT_ANISOTROPY_USED) - float alpha_ggx = roughness * roughness; float aspect = sqrt(1.0 - anisotropy * 0.9); float ax = alpha_ggx / aspect; float ay = alpha_ggx * aspect; float XdotH = dot(T, H); float YdotH = dot(B, H); float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); - float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH); - -#else - float alpha_ggx = roughness * roughness; + float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL); +#else // LIGHT_ANISOTROPY_USED float D = D_GGX(cNdotH, alpha_ggx); - float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx); -#endif - // F + float G = V_GGX(cNdotL, cNdotV, alpha_ggx); +#endif // LIGHT_ANISOTROPY_USED + // F float cLdotH5 = SchlickFresnel(cLdotH); vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0); @@ -263,18 +207,23 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #endif #if defined(LIGHT_CLEARCOAT_USED) + // Clearcoat ignores normal_map, use vertex normal instead + float ccNdotL = max(min(A + dot(vertex_normal, L), 1.0), 0.0); + float ccNdotH = clamp(A + dot(vertex_normal, H), 0.0, 1.0); + float ccNdotV = max(dot(vertex_normal, V), 1e-4); #if !defined(SPECULAR_SCHLICK_GGX) float cLdotH5 = SchlickFresnel(cLdotH); #endif - float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss)); + float Dr = D_GGX(ccNdotH, mix(0.001, 0.1, clearcoat_roughness)); + float Gr = 0.25 / (cLdotH * cLdotH); float Fr = mix(.04, 1.0, cLdotH5); - float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25); - - float clearcoat_specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL; + float clearcoat_specular_brdf_NL = clearcoat * Gr * Fr * Dr * cNdotL; specular_light += clearcoat_specular_brdf_NL * light_color * attenuation * specular_amount; -#endif + // TODO: Clearcoat adds light to the scene right now (it is non-energy conserving), both diffuse and specular need to be scaled by (1.0 - FR) + // but to do so we need to rearrange this entire function +#endif // LIGHT_CLEARCOAT_USED } #ifdef USE_SHADOW_TO_OPACITY @@ -587,7 +536,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float rim, float rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, + float clearcoat, float clearcoat_roughness, vec3 vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED vec3 binormal, vec3 tangent, float anisotropy, @@ -711,7 +660,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v rim * omni_attenuation, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, @@ -827,7 +776,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float rim, float rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - float clearcoat, float clearcoat_gloss, + float clearcoat, float clearcoat_roughness, vec3 vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED vec3 binormal, vec3 tangent, float anisotropy, @@ -877,17 +826,17 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)); splane /= splane.w; - vec2 proj_uv = normal_to_panorama(splane.xyz) * spot_lights.data[idx].projector_rect.zw; + vec2 proj_uv = splane.xy * spot_lights.data[idx].projector_rect.zw; if (sc_projector_use_mipmaps) { //ensure we have proper mipmaps vec4 splane_ddx = (spot_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddx, 1.0)); splane_ddx /= splane_ddx.w; - vec2 proj_uv_ddx = normal_to_panorama(splane_ddx.xyz) * spot_lights.data[idx].projector_rect.zw - proj_uv; + vec2 proj_uv_ddx = splane_ddx.xy * spot_lights.data[idx].projector_rect.zw - proj_uv; vec4 splane_ddy = (spot_lights.data[idx].shadow_matrix * vec4(vertex + vertex_ddy, 1.0)); splane_ddy /= splane_ddy.w; - vec2 proj_uv_ddy = normal_to_panorama(splane_ddy.xyz) * spot_lights.data[idx].projector_rect.zw - proj_uv; + vec2 proj_uv_ddy = splane_ddy.xy * spot_lights.data[idx].projector_rect.zw - proj_uv; vec4 proj = textureGrad(sampler2D(decal_atlas_srgb, light_projector_sampler), proj_uv + spot_lights.data[idx].projector_rect.xy, proj_uv_ddx, proj_uv_ddy); color *= proj.rgb * proj.a; @@ -912,7 +861,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v rim * spot_attenuation, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, vertex_normal, #endif #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index 4d6a3b5864..0fcf449659 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -511,8 +511,8 @@ layout(location = 0) out mediump vec4 frag_color; #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) -/* Make a default specular mode SPECULAR_SCHLICK_GGX. */ -#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN) && !defined(SPECULAR_PHONG) && !defined(SPECULAR_TOON) +// Default to SPECULAR_SCHLICK_GGX. +#if !defined(SPECULAR_DISABLED) && !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_TOON) #define SPECULAR_SCHLICK_GGX #endif @@ -596,7 +596,7 @@ void main() { float rim = 0.0; float rim_tint = 0.0; float clearcoat = 0.0; - float clearcoat_gloss = 0.0; + float clearcoat_roughness = 0.0; float anisotropy = 0.0; vec2 anisotropy_flow = vec2(1.0, 0.0); vec4 fog = vec4(0.0); @@ -874,7 +874,16 @@ void main() { #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) if (scene_data.use_reflection_cubemap) { +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); + vec3 ref_vec = reflect(-view, bent_normal); +#else vec3 ref_vec = reflect(-view, normal); +#endif float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; #ifdef USE_RADIANCE_CUBEMAP_ARRAY @@ -917,7 +926,35 @@ void main() { #if defined(CUSTOM_IRRADIANCE_USED) ambient_light = mix(specular_light, custom_irradiance.rgb, custom_irradiance.a); #endif // CUSTOM_IRRADIANCE_USED +#ifdef LIGHT_CLEARCOAT_USED + + if (scene_data.use_reflection_cubemap) { + vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map + float NoV = max(dot(n, view), 0.0001); + vec3 ref_vec = reflect(-view, n); + // The clear coat layer assumes an IOR of 1.5 (4% reflectance) + float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV)); + float attenuation = 1.0 - Fc; + ambient_light *= attenuation; + specular_light *= attenuation; + + float horizon = min(1.0 + dot(ref_vec, normal), 1.0); + ref_vec = scene_data.radiance_inverse_xform * ref_vec; + float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; +#ifdef USE_RADIANCE_CUBEMAP_ARRAY + + float lod, blend; + blend = modf(roughness_lod, lod); + vec3 clearcoat_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; + clearcoat_light = mix(clearcoat_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); +#else + vec3 clearcoat_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness_lod).rgb; + +#endif //USE_RADIANCE_CUBEMAP_ARRAY + specular_light += clearcoat_light * horizon * horizon * Fc * scene_data.ambient_light_color_energy.a; + } +#endif #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) //radiance @@ -1002,13 +1039,27 @@ void main() { if (reflection_index == 0xFF) { break; } - - reflection_process(reflection_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); +#ifdef LIGHT_ANISOTROPY_USED + // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy + vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; + vec3 anisotropic_tangent = cross(anisotropic_direction, view); + vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction); + vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0))); +#else + vec3 bent_normal = normal; +#endif + reflection_process(reflection_index, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } if (reflection_accum.a > 0.0) { specular_light = reflection_accum.rgb / reflection_accum.a; } + +#if !defined(USE_LIGHTMAP) + if (ambient_accum.a > 0.0) { + ambient_light = ambient_accum.rgb / ambient_accum.a; + } +#endif } //Reflection probes // finalize ambient light here @@ -1079,7 +1130,6 @@ void main() { float depth_z = -vertex.z; vec4 pssm_coord; - vec3 shadow_color = vec3(0.0); vec3 light_dir = directional_lights.data[i].direction; #define BIAS_FUNC(m_var, m_idx) \ @@ -1105,9 +1155,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color1.rgb; - } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); @@ -1125,8 +1172,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); @@ -1144,9 +1189,6 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color3.rgb; - } else { vec4 v = vec4(vertex, 1.0); @@ -1164,12 +1206,9 @@ void main() { } else { shadow = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); } - - shadow_color = directional_lights.data[i].shadow_color4.rgb; } if (directional_lights.data[i].blend_splits) { - vec3 shadow_color_blend = vec3(0.0); float pssm_blend; float shadow2; @@ -1190,7 +1229,6 @@ void main() { } pssm_blend = smoothstep(0.0, directional_lights.data[i].shadow_split_offsets.x, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color2.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 2) @@ -1208,8 +1246,6 @@ void main() { } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.x, directional_lights.data[i].shadow_split_offsets.y, depth_z); - - shadow_color_blend = directional_lights.data[i].shadow_color3.rgb; } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 3) @@ -1226,7 +1262,6 @@ void main() { } pssm_blend = smoothstep(directional_lights.data[i].shadow_split_offsets.y, directional_lights.data[i].shadow_split_offsets.z, depth_z); - shadow_color_blend = directional_lights.data[i].shadow_color4.rgb; } else { pssm_blend = 0.0; //if no blend, same coord will be used (divide by z will result in same value, and already cached) } @@ -1234,7 +1269,6 @@ void main() { pssm_blend = sqrt(pssm_blend); shadow = mix(shadow, shadow2, pssm_blend); - shadow_color = mix(shadow_color, shadow_color_blend, pssm_blend); } shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance @@ -1368,7 +1402,7 @@ void main() { rim, rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED binormal, tangent, anisotropy, @@ -1415,10 +1449,11 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, + binormal, anisotropy, #endif diffuse_light, specular_light); } @@ -1459,10 +1494,11 @@ void main() { rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_gloss, + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, binormal, anisotropy, + tangent, + binormal, anisotropy, #endif diffuse_light, specular_light); } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl index a9a4fce82a..7a624c3b95 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl @@ -7,7 +7,7 @@ #include "decal_data_inc.glsl" -#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) +#if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) #ifndef NORMAL_USED #define NORMAL_USED #endif @@ -15,7 +15,7 @@ /* don't exceed 128 bytes!! */ /* put instance data into our push content, not a array */ -layout(push_constant, binding = 0, std430) uniform DrawCall { +layout(push_constant, std430) uniform DrawCall { highp mat4 transform; // 64 - 64 uint flags; // 04 - 68 uint instance_uniforms_ofs; //base offset in global buffer for instance variables // 04 - 72 diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl index 57349e55b1..a416891ff2 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl @@ -15,7 +15,7 @@ layout(r8, set = 1, binding = 1) uniform restrict writeonly image2D blur_radius_ layout(rgba8, set = 2, binding = 0) uniform restrict readonly image2D source_normal_roughness; layout(set = 3, binding = 0) uniform sampler2D source_metallic; -layout(push_constant, binding = 2, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec4 proj_info; ivec2 screen_size; diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl index 62d1cffb0a..20e1712496 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl @@ -16,7 +16,7 @@ layout(r8, set = 2, binding = 1) uniform restrict writeonly image2D dest_radius; #endif layout(r32f, set = 3, binding = 0) uniform restrict readonly image2D source_depth; -layout(push_constant, binding = 2, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec4 proj_info; bool orthogonal; diff --git a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl index 2328effe7b..3f537e273a 100644 --- a/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl +++ b/servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl @@ -13,7 +13,7 @@ layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly image2D dest_ss layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_depth; layout(rgba8, set = 3, binding = 1) uniform restrict writeonly image2D dest_normal; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 screen_size; float camera_z_near; float camera_z_far; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl index 8b58796962..802a410825 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl @@ -32,7 +32,7 @@ layout(rgba16f, set = 0, binding = 10) uniform restrict writeonly image2D screen layout(set = 0, binding = 11) uniform texture2DArray lightprobe_texture; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec3 grid_size; uint max_cascades; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl index 4290d5b869..e0be0bca12 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl @@ -6,7 +6,7 @@ #define MAX_CASCADES 8 -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { mat4 projection; uint band_power; @@ -160,7 +160,7 @@ layout(location = 0) out vec4 frag_color; layout(set = 0, binding = 2) uniform texture2DArray lightprobe_texture; layout(set = 0, binding = 3) uniform sampler linear_sampler; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { mat4 projection; uint band_power; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl index d6e5c6a92e..b95fad650e 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl @@ -70,8 +70,6 @@ struct Light { float cos_spot_angle; float inv_spot_attenuation; float radius; - - vec4 shadow_color; }; layout(set = 0, binding = 9, std140) buffer restrict readonly Lights { @@ -82,7 +80,7 @@ lights; layout(set = 0, binding = 10) uniform texture2DArray lightprobe_texture; layout(set = 0, binding = 11) uniform texture3D occlusion_texture; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec3 grid_size; uint max_cascades; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl index eedd28959c..9c03297f5c 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl @@ -52,7 +52,7 @@ layout(set = 1, binding = 1) uniform sampler linear_sampler_mipmaps; #define SKY_MODE_COLOR 1 #define SKY_MODE_SKY 2 -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec3 grid_size; uint max_cascades; diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl index f6ec249b5e..bce98f4054 100644 --- a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl @@ -155,7 +155,7 @@ layout(r16ui, set = 0, binding = 2) uniform restrict readonly uimage3D src_occlu #endif -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec3 scroll; int grid_size; diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index b831005256..4ef6a26443 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -36,7 +36,7 @@ layout(set = 2, binding = 0, std430) buffer restrict readonly SkeletonData { } bone_transforms; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { bool has_normal; bool has_tangent; bool has_skeleton; diff --git a/servers/rendering/renderer_rd/shaders/sky.glsl b/servers/rendering/renderer_rd/shaders/sky.glsl index d07a454ade..5b4594da99 100644 --- a/servers/rendering/renderer_rd/shaders/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/sky.glsl @@ -12,7 +12,7 @@ layout(location = 0) out vec2 uv_interp; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { mat3 orientation; vec4 projections[MAX_VIEWS]; vec4 position_multiplier; @@ -52,7 +52,7 @@ void main() { layout(location = 0) in vec2 uv_interp; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { mat3 orientation; vec4 projections[MAX_VIEWS]; vec4 position_multiplier; @@ -180,12 +180,11 @@ void main() { cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projections[ViewIndex].x)) / params.projections[ViewIndex].y; cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projections[ViewIndex].z)) / params.projections[ViewIndex].w; cube_normal = mat3(params.orientation) * cube_normal; - cube_normal.z = -cube_normal.z; cube_normal = normalize(cube_normal); vec2 uv = uv_interp * 0.5 + 0.5; - vec2 panorama_coords = vec2(atan(cube_normal.x, cube_normal.z), acos(cube_normal.y)); + vec2 panorama_coords = vec2(atan(cube_normal.x, -cube_normal.z), acos(cube_normal.y)); if (panorama_coords.x < 0.0) { panorama_coords.x += M_PI * 2.0; @@ -200,13 +199,11 @@ void main() { vec4 custom_fog = vec4(0.0); #ifdef USE_CUBEMAP_PASS - vec3 inverted_cube_normal = cube_normal; - inverted_cube_normal.z *= -1.0; #ifdef USES_HALF_RES_COLOR - half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier; + half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) * params.luminance_multiplier; #endif #ifdef USES_QUARTER_RES_COLOR - quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), inverted_cube_normal) * params.luminance_multiplier; + quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) * params.luminance_multiplier; #endif #else #ifdef USES_HALF_RES_COLOR diff --git a/servers/rendering/renderer_rd/shaders/sort.glsl b/servers/rendering/renderer_rd/shaders/sort.glsl index 307e60dc21..48cf69012a 100644 --- a/servers/rendering/renderer_rd/shaders/sort.glsl +++ b/servers/rendering/renderer_rd/shaders/sort.glsl @@ -47,7 +47,7 @@ layout(set = 1, binding = 0, std430) restrict buffer SortBuffer { } sort_buffer; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { uint total_elements; uint pad[3]; ivec4 job_params; diff --git a/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl b/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl index bdabc146d8..134aae5ce7 100644 --- a/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl +++ b/servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl @@ -25,7 +25,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec2 pixel_size; float z_far; float z_near; diff --git a/servers/rendering/renderer_rd/shaders/ssao.glsl b/servers/rendering/renderer_rd/shaders/ssao.glsl index 18cab75c3b..2a87e273bc 100644 --- a/servers/rendering/renderer_rd/shaders/ssao.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao.glsl @@ -85,7 +85,7 @@ counter; layout(rg8, set = 2, binding = 0) uniform restrict writeonly image2D dest_image; // This push_constant is full - 128 bytes - if you need to add more data, consider adding to the uniform buffer instead -layout(push_constant, binding = 3, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 screen_size; int pass; int quality; diff --git a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl index b154f5e527..f42734c46d 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_blur.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_blur.glsl @@ -29,7 +29,7 @@ layout(set = 0, binding = 0) uniform sampler2D source_ssao; layout(rg8, set = 1, binding = 0) uniform restrict writeonly image2D dest_image; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { float edge_sharpness; float pad; vec2 half_screen_pixel_size; diff --git a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl index 23eba34d63..04f98964e8 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl @@ -39,7 +39,7 @@ layout(set = 2, binding = 0, std430) buffer Counter { counter; #endif -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec2 half_screen_pixel_size; float intensity; float power; diff --git a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl b/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl index 0907423d5d..f6a9a92fac 100644 --- a/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl +++ b/servers/rendering/renderer_rd/shaders/ssao_interleave.glsl @@ -27,7 +27,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; layout(rgba8, set = 0, binding = 0) uniform restrict writeonly image2D dest_image; layout(set = 1, binding = 0) uniform sampler2DArray source_texture; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { float inv_sharpness; uint size_modifier; vec2 pixel_size; diff --git a/servers/rendering/renderer_rd/shaders/ssil.glsl b/servers/rendering/renderer_rd/shaders/ssil.glsl index d1f8f42790..513791dfbf 100644 --- a/servers/rendering/renderer_rd/shaders/ssil.glsl +++ b/servers/rendering/renderer_rd/shaders/ssil.glsl @@ -87,7 +87,7 @@ layout(set = 3, binding = 1) uniform ProjectionConstants { } projection_constants; -layout(push_constant, binding = 3, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 screen_size; int pass; int quality; diff --git a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl b/servers/rendering/renderer_rd/shaders/ssil_blur.glsl index 11861e261f..ee21d46a74 100644 --- a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl +++ b/servers/rendering/renderer_rd/shaders/ssil_blur.glsl @@ -12,7 +12,7 @@ layout(rgba16, set = 1, binding = 0) uniform restrict writeonly image2D dest_ima layout(r8, set = 2, binding = 0) uniform restrict readonly image2D source_edges; -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { float edge_sharpness; float pad; vec2 half_screen_pixel_size; diff --git a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl b/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl index 815aa55fd4..8818f8cada 100644 --- a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl +++ b/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl @@ -39,7 +39,7 @@ layout(set = 2, binding = 0, std430) buffer Counter { counter; #endif -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec2 half_screen_pixel_size; float intensity; float pad; diff --git a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl b/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl index 8a7a5ae4fd..fa4309353d 100644 --- a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl +++ b/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl @@ -10,7 +10,7 @@ layout(rgba16, set = 0, binding = 0) uniform restrict writeonly image2D dest_ima 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 { +layout(push_constant, std430) uniform Params { float inv_sharpness; uint size_modifier; vec2 pixel_size; diff --git a/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl index 9367b641c2..fb35d3cde6 100644 --- a/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl +++ b/servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl @@ -87,7 +87,7 @@ const vec4 skin_kernel[kernel_size] = vec4[]( #endif //USE_11_SAMPLES -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec2 screen_size; float camera_z_far; float camera_z_near; diff --git a/servers/rendering/renderer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl index 41d41758f4..19a9350137 100644 --- a/servers/rendering/renderer_rd/shaders/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl @@ -53,7 +53,7 @@ layout(set = 3, binding = 0) uniform sampler2D source_color_correction; layout(set = 3, binding = 0) uniform sampler3D source_color_correction; #endif -layout(push_constant, binding = 1, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec3 bcs; bool use_bcs; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl index 181d3b272f..a2a4c91894 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl @@ -33,7 +33,7 @@ layout(set = 0, binding = 2, std430) restrict readonly buffer GlobalVariableData } global_variables; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { vec3 position; float pad; diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl index 7c8d4f7f99..347fd13b28 100644 --- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl @@ -235,7 +235,6 @@ void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, uint item_min_max = cluster_buffer.data[p_offset]; item_min = item_min_max & 0xFFFF; item_max = item_min_max >> 16; - ; item_from = item_min >> 5; item_to = (item_max == 0) ? 0 : ((item_max - 1) >> 5) + 1; //side effect of how it is stored, as item_max 0 means no elements @@ -383,7 +382,6 @@ void main() { float depth_z = -view_pos.z; vec4 pssm_coord; - vec3 shadow_color = directional_lights.data[i].shadow_color1.rgb; vec3 light_dir = directional_lights.data[i].direction; vec4 v = vec4(view_pos, 1.0); float z_range; @@ -414,7 +412,7 @@ void main() { shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance - shadow_attenuation = mix(shadow_color, vec3(1.0), shadow); + shadow_attenuation = mix(vec3(0.0), vec3(1.0), shadow); } total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g); diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl index 73a97d9df1..577c6d0cd0 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi.glsl @@ -74,7 +74,7 @@ layout(set = 0, binding = 5) uniform texture3D color_texture; #ifndef MODE_DYNAMIC -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec3 limits; uint stack_size; @@ -108,7 +108,7 @@ layout(rgba8, set = 0, binding = 5) uniform restrict writeonly image3D color_tex #ifdef MODE_DYNAMIC -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec3 limits; uint light_count; //when not lighting ivec3 x_dir; diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl index 3f3437f527..fd7a2bf8ad 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl @@ -20,7 +20,7 @@ layout(set = 0, binding = 2) uniform texture3D color_tex; layout(set = 0, binding = 3) uniform sampler tex_sampler; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { mat4 projection; uint cell_offset; float dynamic_range; diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl index 3bb4421646..47a611a543 100644 --- a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl +++ b/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl @@ -33,7 +33,7 @@ cell_data; layout(r8ui, set = 0, binding = 3) uniform restrict writeonly uimage3D sdf_tex; -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { uint offset; uint end; uint pad0; @@ -66,7 +66,7 @@ void main() { } #if 0 -layout(push_constant, binding = 0, std430) uniform Params { +layout(push_constant, std430) uniform Params { ivec3 limits; uint stack_size; } diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp new file mode 100644 index 0000000000..5843b9db24 --- /dev/null +++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.cpp @@ -0,0 +1,64 @@ +/*************************************************************************/ +/* uniform_set_cache_rd.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "uniform_set_cache_rd.h" + +UniformSetCacheRD *UniformSetCacheRD::singleton = nullptr; + +void UniformSetCacheRD::_invalidate(Cache *p_cache) { + if (p_cache->prev) { + p_cache->prev->next = p_cache->next; + } else { + // At begining of table + uint32_t table_idx = p_cache->hash % HASH_TABLE_SIZE; + hash_table[table_idx] = p_cache->next; + } + + if (p_cache->next) { + p_cache->next->prev = p_cache->prev; + } + + cache_allocator.free(p_cache); + cache_instances_used--; +} +void UniformSetCacheRD::_uniform_set_invalidation_callback(void *p_userdata) { + singleton->_invalidate(reinterpret_cast<Cache *>(p_userdata)); +} + +UniformSetCacheRD::UniformSetCacheRD() { + ERR_FAIL_COND(singleton != nullptr); + singleton = this; +} + +UniformSetCacheRD::~UniformSetCacheRD() { + if (cache_instances_used > 0) { + ERR_PRINT("At exit: " + itos(cache_instances_used) + " uniform set cache instance(s) still in use."); + } +} diff --git a/servers/rendering/renderer_rd/uniform_set_cache_rd.h b/servers/rendering/renderer_rd/uniform_set_cache_rd.h new file mode 100644 index 0000000000..e49cf4dafa --- /dev/null +++ b/servers/rendering/renderer_rd/uniform_set_cache_rd.h @@ -0,0 +1,221 @@ +/*************************************************************************/ +/* uniform_set_cache_rd.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef UNIFORM_SET_CACHE_H +#define UNIFORM_SET_CACHE_H + +#include "core/templates/local_vector.h" +#include "core/templates/paged_allocator.h" +#include "servers/rendering/rendering_device.h" + +class UniformSetCacheRD : public Object { + GDCLASS(UniformSetCacheRD, Object) + + struct Cache { + Cache *prev = nullptr; + Cache *next = nullptr; + uint32_t hash = 0; + RID shader; + uint32_t set = 0; + RID cache; + LocalVector<RD::Uniform> uniforms; + }; + + PagedAllocator<Cache> cache_allocator; + + enum { + HASH_TABLE_SIZE = 16381 // Prime + }; + + Cache *hash_table[HASH_TABLE_SIZE] = {}; + + static _FORCE_INLINE_ uint32_t _hash_uniform(const RD::Uniform &u, uint32_t h) { + h = hash_djb2_one_32(u.uniform_type, h); + h = hash_djb2_one_32(u.binding, h); + uint32_t rsize = u.get_id_count(); + for (uint32_t j = 0; j < rsize; j++) { + h = hash_djb2_one_64(u.get_id(j).get_id(), h); + } + return h; + } + + static _FORCE_INLINE_ bool _compare_uniform(const RD::Uniform &a, const RD::Uniform &b) { + if (a.binding != b.binding) { + return false; + } + if (a.uniform_type != b.uniform_type) { + return false; + } + uint32_t rsize = a.get_id_count(); + if (rsize != b.get_id_count()) { + return false; + } + for (uint32_t j = 0; j < rsize; j++) { + if (a.get_id(j) != b.get_id(j)) { + return false; + } + } + return true; + } + + _FORCE_INLINE_ uint32_t _hash_args(uint32_t h, const RD::Uniform &arg) { + return _hash_uniform(arg, h); + } + + template <typename... Args> + uint32_t _hash_args(uint32_t h, const RD::Uniform &arg, Args... args) { + h = _hash_uniform(arg, h); + return _hash_args(h, args...); + } + + _FORCE_INLINE_ bool _compare_args(uint32_t idx, const LocalVector<RD::Uniform> &uniforms, const RD::Uniform &arg) { + return _compare_uniform(uniforms[idx], arg); + } + + template <typename... Args> + _FORCE_INLINE_ bool _compare_args(uint32_t idx, const LocalVector<RD::Uniform> &uniforms, const RD::Uniform &arg, Args... args) { + if (!_compare_uniform(uniforms[idx], arg)) { + return false; + } + return _compare_args(idx + 1, uniforms, args...); + } + + _FORCE_INLINE_ void _create_args(Vector<RD::Uniform> &uniforms, const RD::Uniform &arg) { + uniforms.push_back(arg); + } + + template <typename... Args> + _FORCE_INLINE_ void _create_args(Vector<RD::Uniform> &uniforms, const RD::Uniform &arg, Args... args) { + uniforms.push_back(arg); + _create_args(uniforms, args...); + } + + static UniformSetCacheRD *singleton; + + uint32_t cache_instances_used = 0; + + void _invalidate(Cache *p_cache); + static void _uniform_set_invalidation_callback(void *p_userdata); + + RID _allocate_from_uniforms(RID p_shader, uint32_t p_set, uint32_t p_hash, uint32_t p_table_idx, const Vector<RD::Uniform> &p_uniforms) { + RID rid = RD::get_singleton()->uniform_set_create(p_uniforms, p_shader, p_set); + ERR_FAIL_COND_V(rid.is_null(), rid); + + Cache *c = cache_allocator.alloc(); + c->hash = p_hash; + c->set = p_set; + c->shader = p_shader; + c->cache = rid; + c->uniforms.resize(p_uniforms.size()); + for (uint32_t i = 0; i < c->uniforms.size(); i++) { + c->uniforms[i] = p_uniforms[i]; + } + c->prev = nullptr; + c->next = hash_table[p_table_idx]; + if (hash_table[p_table_idx]) { + hash_table[p_table_idx]->prev = c; + } + hash_table[p_table_idx] = c; + + RD::get_singleton()->uniform_set_set_invalidation_callback(rid, _uniform_set_invalidation_callback, c); + + cache_instances_used++; + + return rid; + } + +public: + template <typename... Args> + RID get_cache(RID p_shader, uint32_t p_set, Args... args) { + uint32_t h = hash_djb2_one_64(p_shader.get_id()); + h = hash_djb2_one_32(p_set, h); + h = _hash_args(h, args...); + + uint32_t table_idx = h % HASH_TABLE_SIZE; + { + const Cache *c = hash_table[table_idx]; + + while (c) { + if (c->hash == h && c->set == p_set && c->shader == p_shader && _compare_args(0, c->uniforms, args...)) { + return c->cache; + } + c = c->next; + } + } + + // Not in cache, create: + + Vector<RD::Uniform> uniforms; + _create_args(uniforms, args...); + + return _allocate_from_uniforms(p_shader, p_set, h, table_idx, uniforms); + } + + template <typename... Args> + RID get_cache_vec(RID p_shader, uint32_t p_set, const Vector<RD::Uniform> &p_uniforms) { + uint32_t h = hash_djb2_one_64(p_shader.get_id()); + h = hash_djb2_one_32(p_set, h); + for (int i = 0; i < p_uniforms.size(); i++) { + h = _hash_uniform(p_uniforms[i], h); + } + + uint32_t table_idx = h % HASH_TABLE_SIZE; + { + const Cache *c = hash_table[table_idx]; + + while (c) { + if (c->hash == h && c->set == p_set && c->shader == p_shader) { + bool all_ok = true; + for (int i = 0; i < p_uniforms.size(); i++) { + if (!_compare_uniform(p_uniforms[i], c->uniforms[i])) { + all_ok = false; + break; + } + } + + if (all_ok) { + return c->cache; + } + } + c = c->next; + } + } + + // Not in cache, create: + return _allocate_from_uniforms(p_shader, p_set, h, table_idx, p_uniforms); + } + + static UniformSetCacheRD *get_singleton() { return singleton; } + + UniformSetCacheRD(); + ~UniformSetCacheRD(); +}; + +#endif // UNIFORMSETCACHE_H diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index 406d946e12..43d5b07869 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -31,7 +31,7 @@ #ifndef RENDERINGSERVERSCENE_H #define RENDERINGSERVERSCENE_H -#include "servers/rendering/renderer_compositor.h" +#include "servers/rendering_server.h" #include "servers/xr/xr_interface.h" class RendererScene { @@ -105,7 +105,7 @@ public: virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0; virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0; - virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0; /* SKY API */ @@ -187,7 +187,7 @@ public: virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; virtual RID shadow_atlas_create() = 0; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = false) = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = true) = 0; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; /* Render Buffers */ diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 5b2be8e174..485cd7ba9d 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2039,7 +2039,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in cull.shadows[p_shadow_index].light_instance = light->instance; for (int i = 0; i < splits; i++) { - RENDER_TIMESTAMP("Culling Directional Light split" + itos(i)); + RENDER_TIMESTAMP("Cull DirectionalLight3D, Split " + itos(i)); // setup a camera matrix for that range! CameraMatrix camera_matrix; @@ -2227,7 +2227,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } for (int i = 0; i < 2; i++) { //using this one ensures that raster deferred will have it - RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i)); + RENDER_TIMESTAMP("Cull OmniLight3D Shadow Paraboloid, Half " + itos(i)); real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); @@ -2295,7 +2295,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons cm.set_perspective(90, 1, radius * 0.005f, radius); for (int i = 0; i < 6; i++) { - RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i)); + RENDER_TIMESTAMP("Cull OmniLight3D Shadow Cube, Side " + itos(i)); //using this one ensures that raster deferred will have it static const Vector3 view_normals[6] = { @@ -2368,7 +2368,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } break; case RS::LIGHT_SPOT: { - RENDER_TIMESTAMP("Culling Spot Light"); + RENDER_TIMESTAMP("Cull SpotLight3D Shadow"); if (max_shadows_used + 1 > MAX_UPDATE_SHADOWS) { return true; @@ -2508,7 +2508,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ RID environment = _render_get_environment(p_camera, p_scenario); - RENDER_TIMESTAMP("Update occlusion buffer") + RENDER_TIMESTAMP("Update Occlusion Buffer") // For now just cull on the first camera RendererSceneOcclusionCull::get_singleton()->buffer_update(p_viewport, camera_data.main_transform, camera_data.main_projection, camera_data.is_ortogonal, RendererThreadPool::singleton->thread_work_pool); @@ -2890,7 +2890,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c scene_render->sdfgi_update(p_render_buffers, p_environment, p_camera_data->main_transform.origin); //update conditions for SDFGI (whether its used or not) } - RENDER_TIMESTAMP("Visibility Dependencies"); + RENDER_TIMESTAMP("Update Visibility Dependencies"); if (scenario->instance_visibility.get_bin_count() > 0) { if (!scenario->viewport_visibility_masks.has(p_viewport)) { @@ -2918,7 +2918,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c } } - RENDER_TIMESTAMP("Culling"); + RENDER_TIMESTAMP("Cull 3D Scene"); //rasterizer->set_camera(p_camera_data->main_transform, p_camera_data.main_projection, p_camera_data.is_ortogonal); @@ -3155,9 +3155,9 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) { //must redraw! - RENDER_TIMESTAMP(">Rendering Light " + itos(i)); + RENDER_TIMESTAMP("> Render Light3D " + itos(i)); light->shadow_dirty = _light_instance_update_shadow(ins, p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_ortogonal, p_camera_data->vaspect, p_shadow_atlas, scenario, p_screen_mesh_lod_threshold); - RENDER_TIMESTAMP("<Rendering Light " + itos(i)); + RENDER_TIMESTAMP("< Render Light3D " + itos(i)); } else { light->shadow_dirty = redraw; } @@ -3217,7 +3217,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c occluders_tex = RSG::viewport->viewport_get_occluder_debug_texture(p_viewport); } - RENDER_TIMESTAMP("Render Scene "); + RENDER_TIMESTAMP("Render 3D Scene"); scene_render->render_scene(p_render_buffers, p_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info); for (uint32_t i = 0; i < max_shadows_used; i++) { @@ -3263,7 +3263,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, } else { environment = scenario->fallback_environment; } - RENDER_TIMESTAMP("Render Empty Scene "); + RENDER_TIMESTAMP("Render Empty 3D Scene"); RendererSceneRender::CameraData camera_data; camera_data.set_camera(Transform3D(), CameraMatrix(), true, false); @@ -3337,7 +3337,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int environment = scenario->fallback_environment; } - RENDER_TIMESTAMP("Render Reflection Probe, Step " + itos(p_step)); + RENDER_TIMESTAMP("Render ReflectionProbe, Step " + itos(p_step)); RendererSceneRender::CameraData camera_data; camera_data.set_camera(xform, cm, false, false); @@ -3345,7 +3345,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int } else { //do roughness postprocess step until it believes it's done - RENDER_TIMESTAMP("Post-Process Reflection Probe, Step " + itos(p_step)); + RENDER_TIMESTAMP("Post-Process ReflectionProbe, Step " + itos(p_step)); return scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance); } @@ -3398,7 +3398,7 @@ void RendererSceneCull::render_probes() { SelfList<InstanceVoxelGIData> *voxel_gi = voxel_gi_update_list.first(); if (voxel_gi) { - RENDER_TIMESTAMP("Render GI Probes"); + RENDER_TIMESTAMP("Render VoxelGI"); } while (voxel_gi) { @@ -3683,6 +3683,15 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { _instance_update_mesh_instance(p_instance); } + if (p_instance->base_type == RS::INSTANCE_PARTICLES) { + // update the process material dependency + + RID particle_material = RSG::storage->particles_get_process_material(p_instance->base); + if (particle_material.is_valid()) { + RSG::storage->material_update_dependency(particle_material, &p_instance->dependency_tracker); + } + } + if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index ed0229f0f9..90d290bef9 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -31,23 +31,18 @@ #ifndef RENDERING_SERVER_SCENE_CULL_H #define RENDERING_SERVER_SCENE_CULL_H -#include "core/templates/bin_sorted_array.h" -#include "core/templates/pass_func.h" -#include "servers/rendering/renderer_compositor.h" - #include "core/math/dynamic_bvh.h" -#include "core/math/geometry_3d.h" -#include "core/math/octree.h" -#include "core/os/semaphore.h" -#include "core/os/thread.h" +#include "core/templates/bin_sorted_array.h" #include "core/templates/local_vector.h" #include "core/templates/paged_allocator.h" #include "core/templates/paged_array.h" +#include "core/templates/pass_func.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" #include "servers/rendering/renderer_scene.h" #include "servers/rendering/renderer_scene_occlusion_cull.h" #include "servers/rendering/renderer_scene_render.h" +#include "servers/rendering/renderer_storage.h" #include "servers/xr/xr_interface.h" class RendererSceneCull : public RendererScene { diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 3eb90ccc4d..5f9c4bb816 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -34,7 +34,6 @@ #include "core/math/camera_matrix.h" #include "core/templates/paged_array.h" #include "servers/rendering/renderer_scene.h" -#include "servers/rendering/renderer_storage.h" class RendererSceneRender { public: @@ -80,11 +79,11 @@ public: /* SHADOW ATLAS API */ virtual RID shadow_atlas_create() = 0; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) = 0; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0; - virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0; virtual int get_directional_light_shadow_size(RID p_light_intance) = 0; virtual void set_directional_shadow_count(int p_count) = 0; diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 43a7778d67..ca3d3a048d 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -317,10 +317,10 @@ public: virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, RS::LightParam p_param, float p_value) = 0; virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; - virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; virtual void light_set_projector(RID p_light, RID p_texture) = 0; virtual void light_set_negative(RID p_light, bool p_enable) = 0; virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; + virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) = 0; virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; virtual void light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) = 0; virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0; @@ -477,6 +477,7 @@ public: virtual void particles_set_speed_scale(RID p_particles, double p_scale) = 0; virtual void particles_set_use_local_coordinates(RID p_particles, bool p_enable) = 0; virtual void particles_set_process_material(RID p_particles, RID p_material) = 0; + virtual RID particles_get_process_material(RID p_particles) const = 0; virtual void particles_set_fixed_fps(RID p_particles, int p_fps) = 0; virtual void particles_set_interpolate(RID p_particles, bool p_enable) = 0; virtual void particles_set_fractional_delta(RID p_particles, bool p_enable) = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 5a84bace2d..b448a15d8e 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -145,7 +145,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) { } void RendererViewport::_draw_3d(Viewport *p_viewport) { - RENDER_TIMESTAMP(">Begin Rendering 3D Scene"); + RENDER_TIMESTAMP("> Render 3D Scene"); Ref<XRInterface> xr_interface; if (p_viewport->use_xr && XRServer::get_singleton() != nullptr) { @@ -170,7 +170,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) { float screen_mesh_lod_threshold = p_viewport->mesh_lod_threshold / float(p_viewport->size.width); RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->self, p_viewport->internal_size, screen_mesh_lod_threshold, p_viewport->shadow_atlas, xr_interface, &p_viewport->render_info); - RENDER_TIMESTAMP("<End Rendering 3D Scene"); + RENDER_TIMESTAMP("< Render 3D Scene"); } void RendererViewport::_draw_viewport(Viewport *p_viewport) { @@ -281,7 +281,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { int shadow_count = 0; int directional_light_count = 0; - RENDER_TIMESTAMP("Cull Canvas Lights"); + RENDER_TIMESTAMP("Cull 2D Lights"); for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); @@ -355,8 +355,8 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::LightOccluderInstance *occluders = nullptr; - RENDER_TIMESTAMP(">Render 2D Shadows"); - RENDER_TIMESTAMP("Cull Occluders"); + RENDER_TIMESTAMP("> Render PointLight2D Shadows"); + RENDER_TIMESTAMP("Cull LightOccluder2Ds"); //make list of occluders for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { @@ -378,13 +378,13 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::Light *light = lights_with_shadow; while (light) { - RENDER_TIMESTAMP("Render Shadow"); + RENDER_TIMESTAMP("Render PointLight2D Shadow"); RSG::canvas_render->light_update_shadow(light->light_internal, shadow_count++, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders); light = light->shadows_next_ptr; } - RENDER_TIMESTAMP("<End rendering 2D Shadows"); + RENDER_TIMESTAMP("< Render PointLight2D Shadows"); } if (directional_lights_with_shadow) { @@ -436,7 +436,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::LightOccluderInstance *occluders = nullptr; - RENDER_TIMESTAMP(">Render Directional 2D Shadows"); + RENDER_TIMESTAMP("> Render DirectionalLight2D Shadows"); //make list of occluders int occ_cullded = 0; @@ -467,7 +467,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { light = light->shadows_next_ptr; } - RENDER_TIMESTAMP("<Render Directional 2D Shadows"); + RENDER_TIMESTAMP("< Render DirectionalLight2D Shadows"); } if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { @@ -548,7 +548,6 @@ void RendererViewport::draw_viewports() { // get our xr interface in case we need it Ref<XRInterface> xr_interface; - XRServer *xr_server = XRServer::get_singleton(); if (xr_server != nullptr) { // let our XR server know we're about to render our frames so we can get our frame timing @@ -567,7 +566,7 @@ void RendererViewport::draw_viewports() { Map<DisplayServer::WindowID, Vector<BlitToScreen>> blit_to_screen_list; //draw viewports - RENDER_TIMESTAMP(">Render Viewports"); + RENDER_TIMESTAMP("> Render Viewports"); //determine what is visible draw_viewports_pass++; @@ -642,7 +641,7 @@ void RendererViewport::draw_viewports() { continue; //should not draw } - RENDER_TIMESTAMP(">Rendering Viewport " + itos(i)); + RENDER_TIMESTAMP("> Render Viewport " + itos(i)); RSG::storage->render_target_set_as_unused(vp->render_target); if (vp->use_xr && xr_interface.is_valid()) { @@ -700,7 +699,7 @@ void RendererViewport::draw_viewports() { vp->update_mode = RS::VIEWPORT_UPDATE_DISABLED; } - RENDER_TIMESTAMP("<Rendering Viewport " + itos(i)); + RENDER_TIMESTAMP("< Render Viewport " + itos(i)); objects_drawn += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] + vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME]; vertices_drawn += vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] + vp->render_info.info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME]; @@ -712,7 +711,7 @@ void RendererViewport::draw_viewports() { total_vertices_drawn = vertices_drawn; total_draw_calls_used = draw_calls_used; - RENDER_TIMESTAMP("<Render Viewports"); + RENDER_TIMESTAMP("< Render Viewports"); //this needs to be called to make screen swapping more efficient RSG::rasterizer->prepare_for_blitting_render_targets(); diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index 7bc8f9961b..2245d9a216 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -91,7 +91,7 @@ public: RID shadow_atlas; int shadow_atlas_size; - bool shadow_atlas_16_bits = false; + bool shadow_atlas_16_bits = true; bool sdf_active; @@ -247,7 +247,7 @@ public: void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform); void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer); - void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false); + void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true); void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv); void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 655a32a805..1880415342 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -500,6 +500,7 @@ public: virtual RID texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data = Vector<Vector<uint8_t>>()) = 0; virtual RID texture_create_shared(const TextureView &p_view, RID p_with_texture) = 0; + virtual RID texture_create_from_extension(TextureType p_type, DataFormat p_format, TextureSamples p_samples, uint64_t p_flags, uint64_t p_image, uint64_t p_width, uint64_t p_height, uint64_t p_depth, uint64_t p_layers) = 0; enum TextureSliceType { TEXTURE_SLICE_2D, @@ -725,16 +726,65 @@ public: struct Uniform { UniformType uniform_type; - int binding; //binding index as specified in shader + int binding; // Binding index as specified in shader. - //for single items, provide one ID, for - //multiple items (declared as arrays in shader), - //provide more - //for sampler with texture, supply two IDs for each. - //accepted IDs are: Sampler, Texture, Uniform Buffer and Texture Buffer - Vector<RID> ids; + private: + // In most cases only one ID is provided per binding, so avoid allocating memory unnecesarily for performance. + RID id; // If only one is provided, this is used. + Vector<RID> ids; // If multiple ones are provided, this is used instead. - Uniform() { + public: + _FORCE_INLINE_ uint32_t get_id_count() const { + return (id.is_valid() ? 1 : ids.size()); + } + + _FORCE_INLINE_ RID get_id(uint32_t p_idx) const { + if (id.is_valid()) { + ERR_FAIL_COND_V(p_idx != 0, RID()); + return id; + } else { + return ids[p_idx]; + } + } + _FORCE_INLINE_ void set_id(uint32_t p_idx, RID p_id) { + if (id.is_valid()) { + ERR_FAIL_COND(p_idx != 0); + id = p_id; + } else { + ids.write[p_idx] = p_id; + } + } + + _FORCE_INLINE_ void append_id(RID p_id) { + if (ids.is_empty()) { + if (id == RID()) { + id = p_id; + } else { + ids.push_back(id); + ids.push_back(p_id); + id = RID(); + } + } else { + ids.push_back(p_id); + } + } + + _FORCE_INLINE_ void clear_ids() { + id = RID(); + ids.clear(); + } + + _FORCE_INLINE_ Uniform(UniformType p_type, int p_binding, RID p_id) { + uniform_type = p_type; + binding = p_binding; + id = p_id; + } + _FORCE_INLINE_ Uniform(UniformType p_type, int p_binding, const Vector<RID> &p_ids) { + uniform_type = p_type; + binding = p_binding; + ids = p_ids; + } + _FORCE_INLINE_ Uniform() { uniform_type = UNIFORM_TYPE_IMAGE; binding = 0; } diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index b07857364b..ee5bf8b891 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -441,23 +441,23 @@ public: RD_SETGET(RD::UniformType, uniform_type) RD_SETGET(int32_t, binding) - void add_id(const RID &p_id) { base.ids.push_back(p_id); } - void clear_ids() { base.ids.clear(); } + void add_id(const RID &p_id) { base.append_id(p_id); } + void clear_ids() { base.clear_ids(); } Array get_ids() const { Array ids; - for (int i = 0; i < base.ids.size(); i++) { - ids.push_back(base.ids[i]); + for (uint32_t i = 0; i < base.get_id_count(); i++) { + ids.push_back(base.get_id(i)); } return ids; } protected: void _set_ids(const Array &p_ids) { - base.ids.clear(); + base.clear_ids(); for (int i = 0; i < p_ids.size(); i++) { RID id = p_ids[i]; ERR_FAIL_COND(id.is_null()); - base.ids.push_back(id); + base.append_id(id); } } static void _bind_methods() { diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 6d2c36537b..4a8944ccdd 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -342,10 +342,10 @@ public: FUNC2(light_set_color, RID, const Color &) FUNC3(light_set_param, RID, LightParam, float) FUNC2(light_set_shadow, RID, bool) - FUNC2(light_set_shadow_color, RID, const Color &) FUNC2(light_set_projector, RID, RID) FUNC2(light_set_negative, RID, bool) FUNC2(light_set_cull_mask, RID, uint32_t) + FUNC5(light_set_distance_fade, RID, bool, float, float, float) FUNC2(light_set_reverse_cull_face_mode, RID, bool) FUNC2(light_set_bake_mode, RID, LightBakeMode) FUNC2(light_set_max_sdfgi_cascade, RID, uint32_t) diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 5b43ca4bcd..812d636a0b 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -609,7 +609,6 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene r_gen_code.uniforms += uniform_defines[i]; } -#if 1 // add up int offset = 0; for (int i = 0; i < uniform_sizes.size(); i++) { @@ -629,41 +628,6 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene if (r_gen_code.uniform_total_size % 16 != 0) { //UBO sizes must be multiples of 16 r_gen_code.uniform_total_size += 16 - (r_gen_code.uniform_total_size % 16); } -#else - // add up - for (int i = 0; i < uniform_sizes.size(); i++) { - if (i > 0) { - int align = uniform_sizes[i - 1] % uniform_alignments[i]; - if (align != 0) { - uniform_sizes[i - 1] += uniform_alignments[i] - align; - } - - uniform_sizes[i] = uniform_sizes[i] + uniform_sizes[i - 1]; - } - } - //offset - r_gen_code.uniform_offsets.resize(uniform_sizes.size()); - for (int i = 0; i < uniform_sizes.size(); i++) { - if (i > 0) - r_gen_code.uniform_offsets[i] = uniform_sizes[i - 1]; - else - r_gen_code.uniform_offsets[i] = 0; - } - /* - for(Map<StringName,SL::ShaderNode::Uniform>::Element *E=pnode->uniforms.front();E;E=E->next()) { - if (SL::is_sampler_type(E->get().type)) { - continue; - } - - } - -*/ - if (uniform_sizes.size()) { - r_gen_code.uniform_total_size = uniform_sizes[uniform_sizes.size() - 1]; - } else { - r_gen_code.uniform_total_size = 0; - } -#endif uint32_t index = p_default_actions.base_varying_index; @@ -1409,148 +1373,4 @@ void ShaderCompiler::initialize(DefaultIdentifierActions p_actions) { } ShaderCompiler::ShaderCompiler() { -#if 0 - - /** SPATIAL SHADER **/ - - actions[RS::SHADER_SPATIAL].renames["WORLD_MATRIX"] = "world_transform"; - actions[RS::SHADER_SPATIAL].renames["INV_CAMERA_MATRIX"] = "camera_inverse_matrix"; - actions[RS::SHADER_SPATIAL].renames["CAMERA_MATRIX"] = "camera_matrix"; - actions[RS::SHADER_SPATIAL].renames["PROJECTION_MATRIX"] = "projection_matrix"; - actions[RS::SHADER_SPATIAL].renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix"; - actions[RS::SHADER_SPATIAL].renames["MODELVIEW_MATRIX"] = "modelview"; - - actions[RS::SHADER_SPATIAL].renames["VERTEX"] = "vertex.xyz"; - actions[RS::SHADER_SPATIAL].renames["NORMAL"] = "normal"; - actions[RS::SHADER_SPATIAL].renames["TANGENT"] = "tangent"; - actions[RS::SHADER_SPATIAL].renames["BINORMAL"] = "binormal"; - actions[RS::SHADER_SPATIAL].renames["POSITION"] = "position"; - actions[RS::SHADER_SPATIAL].renames["UV"] = "uv_interp"; - actions[RS::SHADER_SPATIAL].renames["UV2"] = "uv2_interp"; - actions[RS::SHADER_SPATIAL].renames["COLOR"] = "color_interp"; - actions[RS::SHADER_SPATIAL].renames["POINT_SIZE"] = "gl_PointSize"; - actions[RS::SHADER_SPATIAL].renames["INSTANCE_ID"] = "gl_InstanceID"; - - //builtins - - actions[RS::SHADER_SPATIAL].renames["TIME"] = "time"; - actions[RS::SHADER_SPATIAL].renames["VIEWPORT_SIZE"] = "viewport_size"; - - actions[RS::SHADER_SPATIAL].renames["FRAGCOORD"] = "gl_FragCoord"; - actions[RS::SHADER_SPATIAL].renames["FRONT_FACING"] = "gl_FrontFacing"; - actions[RS::SHADER_SPATIAL].renames["NORMAL_MAP"] = "normal_map"; - actions[RS::SHADER_SPATIAL].renames["NORMAL_MAP_DEPTH"] = "normal_map_depth"; - actions[RS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo"; - actions[RS::SHADER_SPATIAL].renames["ALPHA"] = "alpha"; - actions[RS::SHADER_SPATIAL].renames["METALLIC"] = "metallic"; - actions[RS::SHADER_SPATIAL].renames["SPECULAR"] = "specular"; - actions[RS::SHADER_SPATIAL].renames["ROUGHNESS"] = "roughness"; - actions[RS::SHADER_SPATIAL].renames["RIM"] = "rim"; - actions[RS::SHADER_SPATIAL].renames["RIM_TINT"] = "rim_tint"; - actions[RS::SHADER_SPATIAL].renames["CLEARCOAT"] = "clearcoat"; - actions[RS::SHADER_SPATIAL].renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss"; - actions[RS::SHADER_SPATIAL].renames["ANISOTROPY"] = "anisotropy"; - actions[RS::SHADER_SPATIAL].renames["ANISOTROPY_FLOW"] = "anisotropy_flow"; - actions[RS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength"; - actions[RS::SHADER_SPATIAL].renames["TRANSMISSION"] = "transmission"; - actions[RS::SHADER_SPATIAL].renames["AO"] = "ao"; - actions[RS::SHADER_SPATIAL].renames["AO_LIGHT_AFFECT"] = "ao_light_affect"; - actions[RS::SHADER_SPATIAL].renames["EMISSION"] = "emission"; - actions[RS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord"; - actions[RS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom"; - actions[RS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv"; - actions[RS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture"; - actions[RS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer"; - actions[RS::SHADER_SPATIAL].renames["DEPTH"] = "gl_FragDepth"; - actions[RS::SHADER_SPATIAL].renames["ALPHA_SCISSOR"] = "alpha_scissor"; - actions[RS::SHADER_SPATIAL].renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; - - //for light - actions[RS::SHADER_SPATIAL].renames["VIEW"] = "view"; - actions[RS::SHADER_SPATIAL].renames["LIGHT_COLOR"] = "light_color"; - actions[RS::SHADER_SPATIAL].renames["LIGHT"] = "light"; - actions[RS::SHADER_SPATIAL].renames["ATTENUATION"] = "attenuation"; - actions[RS::SHADER_SPATIAL].renames["DIFFUSE_LIGHT"] = "diffuse_light"; - actions[RS::SHADER_SPATIAL].renames["SPECULAR_LIGHT"] = "specular_light"; - - actions[RS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT"; - actions[RS::SHADER_SPATIAL].usage_defines["RIM"] = "#define LIGHT_USE_RIM\n"; - actions[RS::SHADER_SPATIAL].usage_defines["RIM_TINT"] = "@RIM"; - actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT"] = "#define LIGHT_USE_CLEARCOAT\n"; - actions[RS::SHADER_SPATIAL].usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT"; - actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY"] = "#define LIGHT_USE_ANISOTROPY\n"; - actions[RS::SHADER_SPATIAL].usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY"; - actions[RS::SHADER_SPATIAL].usage_defines["AO"] = "#define ENABLE_AO\n"; - actions[RS::SHADER_SPATIAL].usage_defines["AO_LIGHT_AFFECT"] = "#define ENABLE_AO\n"; - actions[RS::SHADER_SPATIAL].usage_defines["UV"] = "#define ENABLE_UV_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["UV2"] = "#define ENABLE_UV2_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["NORMAL_MAP"] = "#define ENABLE_NORMAL_MAP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP"; - actions[RS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n"; - actions[RS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n"; - actions[RS::SHADER_SPATIAL].usage_defines["ALPHA_SCISSOR"] = "#define ALPHA_SCISSOR_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n"; - - actions[RS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n"; - actions[RS::SHADER_SPATIAL].usage_defines["TRANSMISSION"] = "#define TRANSMISSION_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n"; - - actions[RS::SHADER_SPATIAL].usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - actions[RS::SHADER_SPATIAL].usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n"; - - actions[RS::SHADER_SPATIAL].render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n"; - - bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley"); - - if (!force_lambert) { - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; - } - - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; - - bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx"); - - if (!force_blinn) { - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n"; - } else { - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n"; - } - - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n"; - actions[RS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n"; - - /* PARTICLES SHADER */ - - actions[RS::SHADER_PARTICLES].renames["COLOR"] = "out_color"; - actions[RS::SHADER_PARTICLES].renames["VELOCITY"] = "out_velocity_active.xyz"; - actions[RS::SHADER_PARTICLES].renames["MASS"] = "mass"; - actions[RS::SHADER_PARTICLES].renames["ACTIVE"] = "shader_active"; - actions[RS::SHADER_PARTICLES].renames["RESTART"] = "restart"; - actions[RS::SHADER_PARTICLES].renames["CUSTOM"] = "out_custom"; - actions[RS::SHADER_PARTICLES].renames["TRANSFORM"] = "xform"; - actions[RS::SHADER_PARTICLES].renames["TIME"] = "time"; - actions[RS::SHADER_PARTICLES].renames["LIFETIME"] = "lifetime"; - actions[RS::SHADER_PARTICLES].renames["DELTA"] = "local_delta"; - actions[RS::SHADER_PARTICLES].renames["NUMBER"] = "particle_number"; - actions[RS::SHADER_PARTICLES].renames["INDEX"] = "index"; - actions[RS::SHADER_PARTICLES].renames["GRAVITY"] = "current_gravity"; - actions[RS::SHADER_PARTICLES].renames["EMISSION_TRANSFORM"] = "emission_transform"; - actions[RS::SHADER_PARTICLES].renames["RANDOM_SEED"] = "random_seed"; - - actions[RS::SHADER_PARTICLES].render_mode_defines["disable_force"] = "#define DISABLE_FORCE\n"; - actions[RS::SHADER_PARTICLES].render_mode_defines["disable_velocity"] = "#define DISABLE_VELOCITY\n"; - actions[RS::SHADER_PARTICLES].render_mode_defines["keep_data"] = "#define ENABLE_KEEP_DATA\n"; -#endif } diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 91201b2028..7683cf20b3 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "shader_language.h" + #include "core/os/os.h" #include "core/string/print_string.h" #include "servers/rendering_server.h" @@ -632,7 +633,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { 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"); } diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index b8bb211a7a..9ea98dc593 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -121,7 +121,7 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["RIM"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["RIM_TINT"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT"] = ShaderLanguage::TYPE_FLOAT; - shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT_GLOSS"] = ShaderLanguage::TYPE_FLOAT; + shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["CLEARCOAT_ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["ANISOTROPY_FLOW"] = ShaderLanguage::TYPE_VEC2; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT; @@ -202,7 +202,7 @@ ShaderTypes::ShaderTypes() { 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({ "specular", "schlick_ggx", "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" }); @@ -318,6 +318,12 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["MASS"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["USERDATA1"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["USERDATA2"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["USERDATA3"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["USERDATA4"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["USERDATA5"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["USERDATA6"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4; shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["LIFETIME"] = constt(ShaderLanguage::TYPE_FLOAT); shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["DELTA"] = constt(ShaderLanguage::TYPE_FLOAT); @@ -338,6 +344,12 @@ ShaderTypes::ShaderTypes() { shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["ACTIVE"] = ShaderLanguage::TYPE_BOOL; shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["RESTART"] = constt(ShaderLanguage::TYPE_BOOL); shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["CUSTOM"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["USERDATA1"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["USERDATA2"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["USERDATA3"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["USERDATA4"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["USERDATA5"] = ShaderLanguage::TYPE_VEC4; + shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["USERDATA6"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_PARTICLES].functions["process"].built_ins["TRANSFORM"] = ShaderLanguage::TYPE_MAT4; 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); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index ac181cb5eb..a6992014e8 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -429,7 +429,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], &value, 4); } - } else { // if (type == Variant::PACKED_FLOAT64_ARRAY) + } else { // PACKED_FLOAT64_ARRAY Vector<double> array = p_arrays[ai]; ERR_FAIL_COND_V(array.size() != p_vertex_array_len * 4, ERR_INVALID_PARAMETER); const double *src = array.ptr(); @@ -573,7 +573,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint memcpy(&sw[p_offsets[ai] + i * p_skin_stride], data, 2 * bone_count); } } - } else { // if (type == Variant::PACKED_FLOAT64_ARRAY) + } else { // PACKED_FLOAT64_ARRAY Vector<double> array = p_arrays[ai]; ERR_FAIL_COND_V(array.size() != (int32_t)(p_vertex_array_len * bone_count), ERR_INVALID_PARAMETER); const double *src = array.ptr(); @@ -1879,10 +1879,10 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("light_set_color", "light", "color"), &RenderingServer::light_set_color); ClassDB::bind_method(D_METHOD("light_set_param", "light", "param", "value"), &RenderingServer::light_set_param); ClassDB::bind_method(D_METHOD("light_set_shadow", "light", "enabled"), &RenderingServer::light_set_shadow); - ClassDB::bind_method(D_METHOD("light_set_shadow_color", "light", "color"), &RenderingServer::light_set_shadow_color); ClassDB::bind_method(D_METHOD("light_set_projector", "light", "texture"), &RenderingServer::light_set_projector); ClassDB::bind_method(D_METHOD("light_set_negative", "light", "enable"), &RenderingServer::light_set_negative); ClassDB::bind_method(D_METHOD("light_set_cull_mask", "light", "mask"), &RenderingServer::light_set_cull_mask); + ClassDB::bind_method(D_METHOD("light_set_distance_fade", "decal", "enabled", "begin", "shadow", "length"), &RenderingServer::light_set_distance_fade); ClassDB::bind_method(D_METHOD("light_set_reverse_cull_face_mode", "light", "enabled"), &RenderingServer::light_set_reverse_cull_face_mode); ClassDB::bind_method(D_METHOD("light_set_bake_mode", "light", "bake_mode"), &RenderingServer::light_set_bake_mode); ClassDB::bind_method(D_METHOD("light_set_max_sdfgi_cascade", "light", "cascade"), &RenderingServer::light_set_max_sdfgi_cascade); @@ -2371,10 +2371,10 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC); BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_DISABLED); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_LOW); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_MEDIUM); - BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_HIGH); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_DISABLED); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_LOW); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_MEDIUM); + BIND_ENUM_CONSTANT(ENV_SSR_ROUGHNESS_QUALITY_HIGH); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_VERY_LOW); BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_LOW); @@ -2388,9 +2388,9 @@ void RenderingServer::_bind_methods() { BIND_ENUM_CONSTANT(ENV_SSIL_QUALITY_HIGH); BIND_ENUM_CONSTANT(ENV_SSIL_QUALITY_ULTRA); - BIND_ENUM_CONSTANT(ENV_SDFGI_Y_SCALE_DISABLED); - BIND_ENUM_CONSTANT(ENV_SDFGI_Y_SCALE_75_PERCENT); BIND_ENUM_CONSTANT(ENV_SDFGI_Y_SCALE_50_PERCENT); + BIND_ENUM_CONSTANT(ENV_SDFGI_Y_SCALE_75_PERCENT); + BIND_ENUM_CONSTANT(ENV_SDFGI_Y_SCALE_100_PERCENT); BIND_ENUM_CONSTANT(ENV_SDFGI_RAY_COUNT_4); BIND_ENUM_CONSTANT(ENV_SDFGI_RAY_COUNT_8); @@ -2580,6 +2580,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture"), &RenderingServer::canvas_item_add_particles); ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &RenderingServer::canvas_item_add_set_transform); ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &RenderingServer::canvas_item_add_clip_ignore); + ClassDB::bind_method(D_METHOD("canvas_item_add_animation_slice", "item", "animation_length", "slice_begin", "slice_end", "offset"), &RenderingServer::canvas_item_add_animation_slice, DEFVAL(0.0)); ClassDB::bind_method(D_METHOD("canvas_item_set_sort_children_by_y", "item", "enabled"), &RenderingServer::canvas_item_set_sort_children_by_y); ClassDB::bind_method(D_METHOD("canvas_item_set_z_index", "item", "z_index"), &RenderingServer::canvas_item_set_z_index); ClassDB::bind_method(D_METHOD("canvas_item_set_z_as_relative_to_parent", "item", "enabled"), &RenderingServer::canvas_item_set_z_as_relative_to_parent); @@ -2830,12 +2831,12 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/shadows/directional_shadow/size", 4096); GLOBAL_DEF("rendering/shadows/directional_shadow/size.mobile", 2048); ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384")); - GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality", 3); + GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality", 2); GLOBAL_DEF("rendering/shadows/directional_shadow/soft_shadow_quality.mobile", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)")); GLOBAL_DEF("rendering/shadows/directional_shadow/16_bits", true); - GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality", 3); + GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality", 2); GLOBAL_DEF("rendering/shadows/shadows/soft_shadow_quality.mobile", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/shadows/shadows/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/shadows/shadows/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Very Low (Faster),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)")); @@ -2860,11 +2861,11 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/shader_compiler/shader_cache/strip_debug", false); GLOBAL_DEF("rendering/shader_compiler/shader_cache/strip_debug.release", true); - GLOBAL_DEF("rendering/reflections/sky_reflections/roughness_layers", 8); + GLOBAL_DEF_RST("rendering/reflections/sky_reflections/roughness_layers", 8); // Assumes a 256x256 cubemap GLOBAL_DEF_RST("rendering/reflections/sky_reflections/texture_array_reflections", true); GLOBAL_DEF("rendering/reflections/sky_reflections/texture_array_reflections.mobile", false); - GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples", 1024); - GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples.mobile", 128); + GLOBAL_DEF_RST("rendering/reflections/sky_reflections/ggx_samples", 32); + GLOBAL_DEF("rendering/reflections/sky_reflections/ggx_samples.mobile", 16); GLOBAL_DEF("rendering/reflections/sky_reflections/fast_filter_high_quality", false); GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size", 256); GLOBAL_DEF("rendering/reflections/reflection_atlas/reflection_size.mobile", 128); @@ -2872,15 +2873,13 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/global_illumination/gi/use_half_resolution", false); - GLOBAL_DEF("rendering/global_illumination/voxel_gi/quality", 1); + GLOBAL_DEF("rendering/global_illumination/voxel_gi/quality", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/voxel_gi/quality", PropertyInfo(Variant::INT, "rendering/global_illumination/voxel_gi/quality", PROPERTY_HINT_ENUM, "Low (4 Cones - Fast),High (6 Cones - Slow)")); GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading", false); GLOBAL_DEF("rendering/shading/overrides/force_vertex_shading.mobile", true); GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley", false); GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true); - GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx", false); - GLOBAL_DEF("rendering/shading/overrides/force_blinn_over_ggx.mobile", true); GLOBAL_DEF("rendering/driver/depth_prepass/enable", true); @@ -2979,7 +2978,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/global_illumination/sdfgi/probe_ray_count", 1); ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/probe_ray_count", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/probe_ray_count", PROPERTY_HINT_ENUM, "8 (Fastest),16,32,64,96,128 (Slowest)")); - GLOBAL_DEF("rendering/global_illumination/sdfgi/frames_to_converge", 4); + GLOBAL_DEF("rendering/global_illumination/sdfgi/frames_to_converge", 5); ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/frames_to_converge", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/frames_to_converge", PROPERTY_HINT_ENUM, "5 (Less Latency but Lower Quality),10,15,20,25,30 (More Latency but Higher Quality)")); GLOBAL_DEF("rendering/global_illumination/sdfgi/frames_to_update_lights", 2); ProjectSettings::get_singleton()->set_custom_property_info("rendering/global_illumination/sdfgi/frames_to_update_lights", PropertyInfo(Variant::INT, "rendering/global_illumination/sdfgi/frames_to_update_lights", PROPERTY_HINT_ENUM, "1 (Slower),2,4,8,16 (Faster)")); @@ -3001,7 +3000,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512); ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1")); - GLOBAL_DEF_RST("rendering/xr/enabled", false); + GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false); GLOBAL_DEF_RST("rendering/2d/options/use_software_skinning", true); GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index d21f3a3299..94d9cb8800 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -439,10 +439,10 @@ public: virtual void light_set_color(RID p_light, const Color &p_color) = 0; virtual void light_set_param(RID p_light, LightParam p_param, float p_value) = 0; virtual void light_set_shadow(RID p_light, bool p_enabled) = 0; - virtual void light_set_shadow_color(RID p_light, const Color &p_color) = 0; virtual void light_set_projector(RID p_light, RID p_texture) = 0; virtual void light_set_negative(RID p_light, bool p_enable) = 0; virtual void light_set_cull_mask(RID p_light, uint32_t p_mask) = 0; + virtual void light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) = 0; virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) = 0; enum LightBakeMode { @@ -473,7 +473,7 @@ public: virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0; virtual void light_directional_set_sky_only(RID p_light, bool p_sky_only) = 0; - virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0; enum ShadowQuality { SHADOW_QUALITY_HARD, @@ -847,7 +847,7 @@ public: virtual void viewport_set_sdf_oversize_and_scale(RID p_viewport, ViewportSDFOversize p_oversize, ViewportSDFScale p_scale) = 0; - virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false) = 0; + virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = true) = 0; virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0; enum ViewportMSAA { @@ -1009,10 +1009,10 @@ public: virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance) = 0; enum EnvironmentSSRRoughnessQuality { - ENV_SSR_ROUGNESS_QUALITY_DISABLED, - ENV_SSR_ROUGNESS_QUALITY_LOW, - ENV_SSR_ROUGNESS_QUALITY_MEDIUM, - ENV_SSR_ROUGNESS_QUALITY_HIGH, + ENV_SSR_ROUGHNESS_QUALITY_DISABLED, + ENV_SSR_ROUGHNESS_QUALITY_LOW, + ENV_SSR_ROUGHNESS_QUALITY_MEDIUM, + ENV_SSR_ROUGHNESS_QUALITY_HIGH, }; virtual void environment_set_ssr_roughness_quality(EnvironmentSSRRoughnessQuality p_quality) = 0; @@ -1042,9 +1042,9 @@ public: 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 EnvironmentSDFGIYScale { - ENV_SDFGI_Y_SCALE_DISABLED, + ENV_SDFGI_Y_SCALE_50_PERCENT, ENV_SDFGI_Y_SCALE_75_PERCENT, - ENV_SDFGI_Y_SCALE_50_PERCENT + ENV_SDFGI_Y_SCALE_100_PERCENT, }; virtual void environment_set_sdfgi(RID p_env, bool p_enable, int p_cascades, float p_min_cell_size, 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; diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp index 3c5faa4ef7..1a10161a5b 100644 --- a/servers/text/text_server_extension.cpp +++ b/servers/text/text_server_extension.cpp @@ -85,6 +85,15 @@ void TextServerExtension::_bind_methods() { GDVIRTUAL_BIND(_font_set_hinting, "font_rid", "hinting"); GDVIRTUAL_BIND(_font_get_hinting, "font_rid"); + GDVIRTUAL_BIND(_font_set_subpixel_positioning, "font_rid", "subpixel_positioning"); + GDVIRTUAL_BIND(_font_get_subpixel_positioning, "font_rid"); + + GDVIRTUAL_BIND(_font_set_embolden, "font_rid", "strength"); + GDVIRTUAL_BIND(_font_get_embolden, "font_rid"); + + GDVIRTUAL_BIND(_font_set_transform, "font_rid", "transform"); + GDVIRTUAL_BIND(_font_get_transform, "font_rid"); + GDVIRTUAL_BIND(_font_set_variation_coordinates, "font_rid", "variation_coordinates"); GDVIRTUAL_BIND(_font_get_variation_coordinates, "font_rid"); @@ -512,6 +521,42 @@ TextServer::Hinting TextServerExtension::font_get_hinting(RID p_font_rid) const return TextServer::Hinting::HINTING_NONE; } +void TextServerExtension::font_set_subpixel_positioning(RID p_font_rid, TextServer::SubpixelPositioning p_subpixel) { + GDVIRTUAL_CALL(_font_set_subpixel_positioning, p_font_rid, p_subpixel); +} + +TextServer::SubpixelPositioning TextServerExtension::font_get_subpixel_positioning(RID p_font_rid) const { + TextServer::SubpixelPositioning ret; + if (GDVIRTUAL_CALL(_font_get_subpixel_positioning, p_font_rid, ret)) { + return (TextServer::SubpixelPositioning)ret; + } + return TextServer::SubpixelPositioning::SUBPIXEL_POSITIONING_DISABLED; +} + +void TextServerExtension::font_set_embolden(RID p_font_rid, float p_strength) { + GDVIRTUAL_CALL(_font_set_embolden, p_font_rid, p_strength); +} + +float TextServerExtension::font_get_embolden(RID p_font_rid) const { + float ret; + if (GDVIRTUAL_CALL(_font_get_embolden, p_font_rid, ret)) { + return ret; + } + return 0.f; +} + +void TextServerExtension::font_set_transform(RID p_font_rid, Transform2D p_transform) { + GDVIRTUAL_CALL(_font_set_transform, p_font_rid, p_transform); +} + +Transform2D TextServerExtension::font_get_transform(RID p_font_rid) const { + Transform2D ret; + if (GDVIRTUAL_CALL(_font_get_transform, p_font_rid, ret)) { + return ret; + } + return Transform2D(); +} + void TextServerExtension::font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) { GDVIRTUAL_CALL(_font_set_variation_coordinates, p_font_rid, p_variation_coordinates); } diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h index 9e7f666be1..7d80467371 100644 --- a/servers/text/text_server_extension.h +++ b/servers/text/text_server_extension.h @@ -134,6 +134,21 @@ public: GDVIRTUAL2(_font_set_hinting, RID, Hinting); GDVIRTUAL1RC(Hinting, _font_get_hinting, RID); + virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) override; + virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_subpixel_positioning, RID, SubpixelPositioning); + GDVIRTUAL1RC(SubpixelPositioning, _font_get_subpixel_positioning, RID); + + virtual void font_set_embolden(RID p_font_rid, float p_strength) override; + virtual float font_get_embolden(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_embolden, RID, float); + GDVIRTUAL1RC(float, _font_get_embolden, RID); + + virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) override; + virtual Transform2D font_get_transform(RID p_font_rid) const override; + GDVIRTUAL2(_font_set_transform, RID, Transform2D); + GDVIRTUAL1RC(Transform2D, _font_get_transform, RID); + virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) override; virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const override; GDVIRTUAL2(_font_set_variation_coordinates, RID, Dictionary); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index b7cd39b9b2..aaba79c049 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -235,9 +235,18 @@ void TextServer::_bind_methods() { ClassDB::bind_method(D_METHOD("font_set_force_autohinter", "font_rid", "force_autohinter"), &TextServer::font_set_force_autohinter); ClassDB::bind_method(D_METHOD("font_is_force_autohinter", "font_rid"), &TextServer::font_is_force_autohinter); - ClassDB::bind_method(D_METHOD("font_set_hinting", "font_rid", "_hinting"), &TextServer::font_set_hinting); + ClassDB::bind_method(D_METHOD("font_set_hinting", "font_rid", "hinting"), &TextServer::font_set_hinting); ClassDB::bind_method(D_METHOD("font_get_hinting", "font_rid"), &TextServer::font_get_hinting); + ClassDB::bind_method(D_METHOD("font_set_subpixel_positioning", "font_rid", "subpixel_positioning"), &TextServer::font_set_subpixel_positioning); + ClassDB::bind_method(D_METHOD("font_get_subpixel_positioning", "font_rid"), &TextServer::font_get_subpixel_positioning); + + ClassDB::bind_method(D_METHOD("font_set_embolden", "font_rid", "strength"), &TextServer::font_set_embolden); + ClassDB::bind_method(D_METHOD("font_get_embolden", "font_rid"), &TextServer::font_get_embolden); + + ClassDB::bind_method(D_METHOD("font_set_transform", "font_rid", "transform"), &TextServer::font_set_transform); + ClassDB::bind_method(D_METHOD("font_get_transform", "font_rid"), &TextServer::font_get_transform); + ClassDB::bind_method(D_METHOD("font_set_variation_coordinates", "font_rid", "variation_coordinates"), &TextServer::font_set_variation_coordinates); ClassDB::bind_method(D_METHOD("font_get_variation_coordinates", "font_rid"), &TextServer::font_get_variation_coordinates); @@ -479,6 +488,12 @@ void TextServer::_bind_methods() { BIND_ENUM_CONSTANT(HINTING_LIGHT); BIND_ENUM_CONSTANT(HINTING_NORMAL); + /* SubpixelPositioning */ + BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_DISABLED); + BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_AUTO); + BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_HALF); + BIND_ENUM_CONSTANT(SUBPIXEL_POSITIONING_ONE_QUARTER); + /* Feature */ BIND_ENUM_CONSTANT(FEATURE_BIDI_LAYOUT); BIND_ENUM_CONSTANT(FEATURE_VERTICAL_LAYOUT); @@ -743,15 +758,19 @@ PackedInt32Array TextServer::shaped_text_get_word_breaks(RID p_shaped, int p_gra for (int i = 0; i < l_size; i++) { if (l_gl[i].count > 0) { if ((l_gl[i].flags & p_grapheme_flags) != 0) { - words.push_back(word_start); - words.push_back(l_gl[i].start); + if (word_start != l_gl[i].start) { + words.push_back(word_start); + words.push_back(l_gl[i].start); + } word_start = l_gl[i].end; } } } if (l_size > 0) { - words.push_back(word_start); - words.push_back(range.y); + if (word_start != range.y) { + words.push_back(word_start); + words.push_back(range.y); + } } return words; @@ -1248,11 +1267,11 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p if (p_clip_r > 0) { // Clip right / bottom. if (orientation == ORIENTATION_HORIZONTAL) { - if (ofs.x - p_pos.x > p_clip_r) { + if (ofs.x - p_pos.x + glyphs[i].advance > p_clip_r) { return; } } else { - if (ofs.y - p_pos.y > p_clip_r) { + if (ofs.y - p_pos.y + glyphs[i].advance > p_clip_r) { return; } } @@ -1343,11 +1362,11 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect if (p_clip_r > 0) { // Clip right / bottom. if (orientation == ORIENTATION_HORIZONTAL) { - if (ofs.x - p_pos.x > p_clip_r) { + if (ofs.x - p_pos.x + glyphs[i].advance > p_clip_r) { return; } } else { - if (ofs.y - p_pos.y > p_clip_r) { + if (ofs.y - p_pos.y + glyphs[i].advance > p_clip_r) { return; } } diff --git a/servers/text_server.h b/servers/text_server.h index 629a633b9f..83dc3df56d 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -101,6 +101,16 @@ public: HINTING_NORMAL }; + enum SubpixelPositioning { + SUBPIXEL_POSITIONING_DISABLED, + SUBPIXEL_POSITIONING_AUTO, + SUBPIXEL_POSITIONING_ONE_HALF, + SUBPIXEL_POSITIONING_ONE_QUARTER, + }; + + const int SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE = 20; + const int SUBPIXEL_POSITIONING_ONE_QUARTER_MAX_SIZE = 16; + enum Feature { FEATURE_BIDI_LAYOUT = 1 << 0, FEATURE_VERTICAL_LAYOUT = 1 << 1, @@ -248,6 +258,15 @@ public: virtual void font_set_hinting(RID p_font_rid, Hinting p_hinting) = 0; virtual Hinting font_get_hinting(RID p_font_rid) const = 0; + virtual void font_set_subpixel_positioning(RID p_font_rid, SubpixelPositioning p_subpixel) = 0; + virtual SubpixelPositioning font_get_subpixel_positioning(RID p_font_rid) const = 0; + + virtual void font_set_embolden(RID p_font_rid, float p_strength) = 0; + virtual float font_get_embolden(RID p_font_rid) const = 0; + + virtual void font_set_transform(RID p_font_rid, Transform2D p_transform) = 0; + virtual Transform2D font_get_transform(RID p_font_rid) const = 0; + virtual void font_set_variation_coordinates(RID p_font_rid, const Dictionary &p_variation_coordinates) = 0; virtual Dictionary font_get_variation_coordinates(RID p_font_rid) const = 0; @@ -551,6 +570,7 @@ VARIANT_ENUM_CAST(TextServer::LineBreakFlag); VARIANT_ENUM_CAST(TextServer::TextOverrunFlag); VARIANT_ENUM_CAST(TextServer::GraphemeFlag); VARIANT_ENUM_CAST(TextServer::Hinting); +VARIANT_ENUM_CAST(TextServer::SubpixelPositioning); VARIANT_ENUM_CAST(TextServer::Feature); VARIANT_ENUM_CAST(TextServer::ContourPointTag); VARIANT_ENUM_CAST(TextServer::SpacingType); diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index 6e105ffc26..62eba2f00b 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -45,7 +45,7 @@ struct BlitToScreen; If the user wants to enable AR/VR the choose the interface they want to use and initialize it. - Note that we may make this into a fully instantiable class for GDNative support. + Note that we may make this into a fully instantiable class for GDExtension support. */ class XRInterface : public RefCounted { diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp index 7b21eeba04..4857167a8e 100644 --- a/servers/xr/xr_positional_tracker.cpp +++ b/servers/xr/xr_positional_tracker.cpp @@ -49,6 +49,10 @@ void XRPositionalTracker::_bind_methods() { ClassDB::bind_method(D_METHOD("set_tracker_desc", "description"), &XRPositionalTracker::set_tracker_desc); ADD_PROPERTY(PropertyInfo(Variant::STRING, "description"), "set_tracker_desc", "get_tracker_desc"); + ClassDB::bind_method(D_METHOD("get_tracker_profile"), &XRPositionalTracker::get_tracker_profile); + ClassDB::bind_method(D_METHOD("set_tracker_profile", "profile"), &XRPositionalTracker::set_tracker_profile); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "profile"), "set_tracker_profile", "get_tracker_profile"); + ClassDB::bind_method(D_METHOD("get_tracker_hand"), &XRPositionalTracker::get_tracker_hand); ClassDB::bind_method(D_METHOD("set_tracker_hand", "hand"), &XRPositionalTracker::set_tracker_hand); ADD_PROPERTY(PropertyInfo(Variant::INT, "hand", PROPERTY_HINT_ENUM, "Unknown,Left,Right"), "set_tracker_hand", "get_tracker_hand"); @@ -65,10 +69,7 @@ void XRPositionalTracker::_bind_methods() { ADD_SIGNAL(MethodInfo("button_released", PropertyInfo(Variant::STRING, "name"))); ADD_SIGNAL(MethodInfo("input_value_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "value"))); ADD_SIGNAL(MethodInfo("input_axis_changed", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::VECTOR2, "vector"))); - - ClassDB::bind_method(D_METHOD("get_rumble"), &XRPositionalTracker::get_rumble); - ClassDB::bind_method(D_METHOD("set_rumble", "rumble"), &XRPositionalTracker::set_rumble); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rumble"), "set_rumble", "get_rumble"); + ADD_SIGNAL(MethodInfo("profile_changed", PropertyInfo(Variant::STRING, "role"))); }; void XRPositionalTracker::set_tracker_type(XRServer::TrackerType p_type) { @@ -99,6 +100,18 @@ String XRPositionalTracker::get_tracker_desc() const { return description; } +void XRPositionalTracker::set_tracker_profile(const String &p_profile) { + if (profile != p_profile) { + profile = p_profile; + + emit_signal("profile_changed", profile); + } +} + +String XRPositionalTracker::get_tracker_profile() const { + return profile; +} + XRPositionalTracker::TrackerHand XRPositionalTracker::get_tracker_hand() const { return hand; }; @@ -206,21 +219,8 @@ void XRPositionalTracker::set_input(const StringName &p_action_name, const Varia } } -real_t XRPositionalTracker::get_rumble() const { - return rumble; -}; - -void XRPositionalTracker::set_rumble(real_t p_rumble) { - if (p_rumble > 0.0) { - rumble = p_rumble; - } else { - rumble = 0.0; - }; -}; - XRPositionalTracker::XRPositionalTracker() { type = XRServer::TRACKER_UNKNOWN; name = "Unknown"; hand = TRACKER_HAND_UNKNOWN; - rumble = 0.0; }; diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index 2f358cbb21..cd06d4a087 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -56,16 +56,13 @@ public: private: XRServer::TrackerType type; // type of tracker StringName name; // (unique) name of the tracker - String description; // description of the tracker, this is interface dependent, for OpenXR this will be the interaction profile bound for to the tracker + String description; // description of the tracker + String profile; // this is interface dependent, for OpenXR this will be the interaction profile bound for to the tracker TrackerHand hand; // if known, the hand this tracker is held in Map<StringName, Ref<XRPose>> poses; Map<StringName, Variant> inputs; - int joy_id; // if we also have a related joystick entity, the id of the joystick - Ref<Mesh> mesh; // when available, a mesh that can be used to render this tracker - real_t rumble; // rumble strength, 0.0 is off, 1.0 is maximum, note that we only record here, xr_interface is responsible for execution - protected: static void _bind_methods(); @@ -76,6 +73,8 @@ public: StringName get_tracker_name() const; void set_tracker_desc(const String &p_desc); String get_tracker_desc() const; + void set_tracker_profile(const String &p_profile); + String get_tracker_profile() const; XRPositionalTracker::TrackerHand get_tracker_hand() const; void set_tracker_hand(const XRPositionalTracker::TrackerHand p_hand); @@ -87,10 +86,6 @@ public: Variant get_input(const StringName &p_action_name) const; void set_input(const StringName &p_action_name, const Variant &p_value); - // TODO replace by new implementation - real_t get_rumble() const; - void set_rumble(real_t p_rumble); - XRPositionalTracker(); ~XRPositionalTracker() {} }; diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp index dbfe76a127..e32b41c7ae 100644 --- a/servers/xr_server.cpp +++ b/servers/xr_server.cpp @@ -348,9 +348,10 @@ PackedStringArray XRServer::get_suggested_pose_names(const StringName &p_tracker } void XRServer::_process() { - /* called from renderer_viewport.draw_viewports right before we start drawing our viewports */ + // called from our main game loop before we handle physics and game logic + // note that we can have multiple interfaces active if we have interfaces that purely handle tracking - /* process all active interfaces */ + // process all active interfaces for (int i = 0; i < interfaces.size(); i++) { if (!interfaces[i].is_valid()) { // ignore, not a valid reference |