summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/SCsub1
-rw-r--r--servers/audio/audio_stream.cpp370
-rw-r--r--servers/audio/audio_stream.h77
-rw-r--r--servers/audio/effects/audio_effect_delay.cpp3
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp96
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.h41
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.cpp1
-rw-r--r--servers/audio_server.cpp4
-rw-r--r--servers/debugger/SCsub5
-rw-r--r--servers/debugger/servers_debugger.cpp463
-rw-r--r--servers/debugger/servers_debugger.h132
-rw-r--r--servers/display_server.cpp7
-rw-r--r--servers/display_server.h3
-rw-r--r--servers/physics_2d/godot_body_pair_2d.cpp5
-rw-r--r--servers/physics_2d/godot_collision_solver_2d_sat.cpp4
-rw-r--r--servers/physics_2d/godot_physics_server_2d.cpp13
-rw-r--r--servers/physics_2d/godot_shape_2d.cpp6
-rw-r--r--servers/physics_2d/godot_space_2d.cpp7
-rw-r--r--servers/physics_3d/gjk_epa.cpp2
-rw-r--r--servers/physics_3d/godot_collision_solver_3d_sat.cpp4
-rw-r--r--servers/physics_3d/godot_physics_server_3d.cpp13
-rw-r--r--servers/physics_3d/godot_shape_3d.cpp6
-rw-r--r--servers/physics_3d/godot_space_3d.cpp7
-rw-r--r--servers/physics_3d/joints/godot_hinge_joint_3d.cpp6
-rw-r--r--servers/physics_server_2d.cpp2
-rw-r--r--servers/physics_server_3d.cpp2
-rw-r--r--servers/register_server_types.cpp7
-rw-r--r--servers/rendering/rasterizer_dummy.h6
-rw-r--r--servers/rendering/renderer_compositor.h4
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp26
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h2
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp7
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp3
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_environment_rd.h8
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp3
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.h10
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp53
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h8
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp100
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h2
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp149
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h26
-rw-r--r--servers/rendering/renderer_rd/shaders/blit.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_sdf.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_debug.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_render.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_store.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/copy.glsl93
-rw-r--r--servers/rendering/renderer_rd/shaders/copy_to_fb.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/cube_to_dp.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl26
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl23
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl24
-rw-r--r--servers/rendering/renderer_rd/shaders/fsr_upscale.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/gi.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_write.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/luminance_reduce.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl20
-rw-r--r--servers/rendering/renderer_rd/shaders/particles_copy.glsl46
-rw-r--r--servers/rendering/renderer_rd/shaders/resolve.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/roughness_limiter.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl1
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl5
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/screen_space_reflection_scale.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/skeleton.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/sky.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/sort.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ss_effects_downsample.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_blur.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_importance_map.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssao_interleave.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_blur.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_interleave.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/tonemap.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl1
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl4
-rw-r--r--servers/rendering/renderer_scene.h6
-rw-r--r--servers/rendering/renderer_scene_cull.cpp9
-rw-r--r--servers/rendering/renderer_scene_cull.h11
-rw-r--r--servers/rendering/renderer_scene_render.h5
-rw-r--r--servers/rendering/renderer_storage.h1
-rw-r--r--servers/rendering/renderer_viewport.h4
-rw-r--r--servers/rendering/shader_compiler.cpp36
-rw-r--r--servers/rendering/shader_language.cpp29
-rw-r--r--servers/rendering/shader_types.cpp12
-rw-r--r--servers/rendering_server.cpp24
-rw-r--r--servers/rendering_server.h10
-rw-r--r--servers/text/text_server_extension.cpp15
-rw-r--r--servers/text/text_server_extension.h5
-rw-r--r--servers/text_server.cpp11
-rw-r--r--servers/text_server.h14
-rw-r--r--servers/xr/xr_positional_tracker.cpp10
116 files changed, 1668 insertions, 591 deletions
diff --git a/servers/SCsub b/servers/SCsub
index 76c11724d3..2cd4741d56 100644
--- a/servers/SCsub
+++ b/servers/SCsub
@@ -12,6 +12,7 @@ SConscript("physics_2d/SCsub")
SConscript("rendering/SCsub")
SConscript("audio/SCsub")
SConscript("text/SCsub")
+SConscript("debugger/SCsub")
lib = env.add_library("servers", env.servers_sources)
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 170a7ef967..39060286a4 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -351,100 +351,372 @@ AudioStreamPlaybackMicrophone::AudioStreamPlaybackMicrophone() {
////////////////////////////////
-void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {
- audio_stream = p_audio_stream;
- if (audio_stream.is_valid()) {
- for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) {
- E->get()->playback = audio_stream->instance_playback();
- }
+void AudioStreamRandomizer::add_stream(int p_index) {
+ if (p_index < 0) {
+ p_index = audio_stream_pool.size();
+ }
+ ERR_FAIL_COND(p_index > audio_stream_pool.size());
+ PoolEntry entry{ nullptr, 1.0f };
+ audio_stream_pool.insert(p_index, entry);
+ emit_signal(SNAME("changed"));
+ notify_property_list_changed();
+}
+
+void AudioStreamRandomizer::move_stream(int p_index_from, int p_index_to) {
+ ERR_FAIL_COND(p_index_from < 0);
+ ERR_FAIL_COND(p_index_from >= audio_stream_pool.size());
+ ERR_FAIL_COND(p_index_to < 0);
+ ERR_FAIL_COND(p_index_to > audio_stream_pool.size());
+ audio_stream_pool.insert(p_index_to, audio_stream_pool[p_index_from]);
+ // If 'from' is strictly after 'to' we need to increment the index by one because of the insertion.
+ if (p_index_from > p_index_to) {
+ p_index_from++;
}
+ audio_stream_pool.remove_at(p_index_from);
+ emit_signal(SNAME("changed"));
+ notify_property_list_changed();
+}
+
+void AudioStreamRandomizer::remove_stream(int p_index) {
+ ERR_FAIL_COND(p_index < 0);
+ ERR_FAIL_COND(p_index >= audio_stream_pool.size());
+ audio_stream_pool.remove_at(p_index);
+ emit_signal(SNAME("changed"));
+ notify_property_list_changed();
+}
+
+void AudioStreamRandomizer::set_stream(int p_index, Ref<AudioStream> p_stream) {
+ ERR_FAIL_COND(p_index < 0);
+ ERR_FAIL_COND(p_index >= audio_stream_pool.size());
+ audio_stream_pool.write[p_index].stream = p_stream;
+ emit_signal(SNAME("changed"));
}
-Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const {
- return audio_stream;
+Ref<AudioStream> AudioStreamRandomizer::get_stream(int p_index) const {
+ ERR_FAIL_COND_V(p_index < 0, nullptr);
+ ERR_FAIL_COND_V(p_index >= audio_stream_pool.size(), nullptr);
+ return audio_stream_pool[p_index].stream;
}
-void AudioStreamRandomPitch::set_random_pitch(float p_pitch) {
+void AudioStreamRandomizer::set_stream_probability_weight(int p_index, float p_weight) {
+ ERR_FAIL_COND(p_index < 0);
+ ERR_FAIL_COND(p_index >= audio_stream_pool.size());
+ audio_stream_pool.write[p_index].weight = p_weight;
+ emit_signal(SNAME("changed"));
+}
+
+float AudioStreamRandomizer::get_stream_probability_weight(int p_index) const {
+ ERR_FAIL_COND_V(p_index < 0, 0);
+ ERR_FAIL_COND_V(p_index >= audio_stream_pool.size(), 0);
+ return audio_stream_pool[p_index].weight;
+}
+
+void AudioStreamRandomizer::set_streams_count(int p_count) {
+ audio_stream_pool.resize(p_count);
+}
+
+int AudioStreamRandomizer::get_streams_count() const {
+ return audio_stream_pool.size();
+}
+
+void AudioStreamRandomizer::set_random_pitch(float p_pitch) {
if (p_pitch < 1) {
p_pitch = 1;
}
- random_pitch = p_pitch;
+ random_pitch_scale = p_pitch;
+}
+
+float AudioStreamRandomizer::get_random_pitch() const {
+ return random_pitch_scale;
+}
+
+void AudioStreamRandomizer::set_random_volume_offset_db(float p_volume_offset_db) {
+ if (p_volume_offset_db < 0) {
+ p_volume_offset_db = 0;
+ }
+ random_volume_offset_db = p_volume_offset_db;
+}
+
+float AudioStreamRandomizer::get_random_volume_offset_db() const {
+ return random_volume_offset_db;
}
-float AudioStreamRandomPitch::get_random_pitch() const {
- return random_pitch;
+void AudioStreamRandomizer::set_playback_mode(PlaybackMode p_playback_mode) {
+ playback_mode = p_playback_mode;
}
-Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() {
- Ref<AudioStreamPlaybackRandomPitch> playback;
+AudioStreamRandomizer::PlaybackMode AudioStreamRandomizer::get_playback_mode() const {
+ return playback_mode;
+}
+
+Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_random() {
+ Ref<AudioStreamPlaybackRandomizer> playback;
playback.instantiate();
- if (audio_stream.is_valid()) {
- playback->playback = audio_stream->instance_playback();
+ playbacks.insert(playback.ptr());
+ playback->randomizer = Ref<AudioStreamRandomizer>((AudioStreamRandomizer *)this);
+
+ double total_weight = 0;
+ Vector<PoolEntry> local_pool;
+ for (const PoolEntry &entry : audio_stream_pool) {
+ if (entry.stream.is_valid() && entry.weight > 0) {
+ local_pool.push_back(entry);
+ total_weight += entry.weight;
+ }
+ }
+ if (local_pool.is_empty()) {
+ return playback;
}
+ double chosen_cumulative_weight = Math::random(0.0, total_weight);
+ double cumulative_weight = 0;
+ for (PoolEntry &entry : local_pool) {
+ cumulative_weight += entry.weight;
+ if (cumulative_weight > chosen_cumulative_weight) {
+ playback->playback = entry.stream->instance_playback();
+ last_playback = entry.stream;
+ break;
+ }
+ }
+ if (playback->playback.is_null()) {
+ // This indicates a floating point error. Take the last element.
+ last_playback = local_pool[local_pool.size() - 1].stream;
+ playback->playback = local_pool.write[local_pool.size() - 1].stream->instance_playback();
+ }
+ return playback;
+}
+
+Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_no_repeats() {
+ Ref<AudioStreamPlaybackRandomizer> playback;
+ double total_weight = 0;
+ Vector<PoolEntry> local_pool;
+ for (const PoolEntry &entry : audio_stream_pool) {
+ if (entry.stream == last_playback) {
+ continue;
+ }
+ if (entry.stream.is_valid() && entry.weight > 0) {
+ local_pool.push_back(entry);
+ total_weight += entry.weight;
+ }
+ }
+ if (local_pool.is_empty()) {
+ playback = instance_playback_random();
+ WARN_PRINT("Playback stream pool is too small to prevent repeats.");
+ return playback;
+ }
+
+ playback.instantiate();
playbacks.insert(playback.ptr());
- playback->random_pitch = Ref<AudioStreamRandomPitch>((AudioStreamRandomPitch *)this);
+ playback->randomizer = Ref<AudioStreamRandomizer>((AudioStreamRandomizer *)this);
+ double chosen_cumulative_weight = Math::random(0.0, total_weight);
+ double cumulative_weight = 0;
+ for (PoolEntry &entry : local_pool) {
+ cumulative_weight += entry.weight;
+ if (cumulative_weight > chosen_cumulative_weight) {
+ last_playback = entry.stream;
+ playback->playback = entry.stream->instance_playback();
+ break;
+ }
+ }
+ if (playback->playback.is_null()) {
+ // This indicates a floating point error. Take the last element.
+ last_playback = local_pool[local_pool.size() - 1].stream;
+ playback->playback = local_pool.write[local_pool.size() - 1].stream->instance_playback();
+ }
return playback;
}
-String AudioStreamRandomPitch::get_stream_name() const {
- if (audio_stream.is_valid()) {
- return "Random: " + audio_stream->get_name();
+Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback_sequential() {
+ Ref<AudioStreamPlaybackRandomizer> playback;
+ playback.instantiate();
+ playbacks.insert(playback.ptr());
+ playback->randomizer = Ref<AudioStreamRandomizer>((AudioStreamRandomizer *)this);
+
+ Vector<Ref<AudioStream>> local_pool;
+ for (const PoolEntry &entry : audio_stream_pool) {
+ if (entry.stream.is_null()) {
+ continue;
+ }
+ if (local_pool.find(entry.stream) != -1) {
+ WARN_PRINT("Duplicate stream in sequential playback pool");
+ continue;
+ }
+ local_pool.push_back(entry.stream);
+ }
+ if (local_pool.is_empty()) {
+ return playback;
}
- return "RandomPitch";
+ bool found_last_stream = false;
+ for (Ref<AudioStream> &entry : local_pool) {
+ if (found_last_stream) {
+ last_playback = entry;
+ playback->playback = entry->instance_playback();
+ break;
+ }
+ if (entry == last_playback) {
+ found_last_stream = true;
+ }
+ }
+ if (playback->playback.is_null()) {
+ // Wrap around
+ last_playback = local_pool[0];
+ playback->playback = local_pool.write[0]->instance_playback();
+ }
+ return playback;
}
-float AudioStreamRandomPitch::get_length() const {
- if (audio_stream.is_valid()) {
- return audio_stream->get_length();
+Ref<AudioStreamPlayback> AudioStreamRandomizer::instance_playback() {
+ switch (playback_mode) {
+ case PLAYBACK_RANDOM:
+ return instance_playback_random();
+ case PLAYBACK_RANDOM_NO_REPEATS:
+ return instance_playback_no_repeats();
+ case PLAYBACK_SEQUENTIAL:
+ return instance_playback_sequential();
+ default:
+ ERR_FAIL_V_MSG(nullptr, "Unhandled playback mode.");
}
+}
+String AudioStreamRandomizer::get_stream_name() const {
+ return "Randomizer";
+}
+
+float AudioStreamRandomizer::get_length() const {
return 0;
}
-bool AudioStreamRandomPitch::is_monophonic() const {
- if (audio_stream.is_valid()) {
- return audio_stream->is_monophonic();
+bool AudioStreamRandomizer::is_monophonic() const {
+ for (const PoolEntry &entry : audio_stream_pool) {
+ if (entry.stream.is_valid() && entry.stream->is_monophonic()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool AudioStreamRandomizer::_get(const StringName &p_name, Variant &r_ret) const {
+ if (AudioStream::_get(p_name, r_ret)) {
+ return true;
}
+ Vector<String> components = String(p_name).split("/", true, 2);
+ if (components.size() == 2 && components[0].begins_with("stream_") && components[0].trim_prefix("stream_").is_valid_int()) {
+ int index = components[0].trim_prefix("stream_").to_int();
+ if (index < 0 || index >= (int)audio_stream_pool.size()) {
+ return false;
+ }
- return true; // It doesn't really matter what we return here, but no sense instancing a many playbacks of a null stream.
+ if (components[1] == "stream") {
+ r_ret = get_stream(index);
+ return true;
+ } else if (components[1] == "weight") {
+ r_ret = get_stream_probability_weight(index);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return false;
+}
+
+bool AudioStreamRandomizer::_set(const StringName &p_name, const Variant &p_value) {
+ if (AudioStream::_set(p_name, p_value)) {
+ return true;
+ }
+ Vector<String> components = String(p_name).split("/", true, 2);
+ if (components.size() == 2 && components[0].begins_with("stream_") && components[0].trim_prefix("stream_").is_valid_int()) {
+ int index = components[0].trim_prefix("stream_").to_int();
+ if (index < 0 || index >= (int)audio_stream_pool.size()) {
+ return false;
+ }
+
+ if (components[1] == "stream") {
+ set_stream(index, p_value);
+ return true;
+ } else if (components[1] == "weight") {
+ set_stream_probability_weight(index, p_value);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return false;
+}
+
+void AudioStreamRandomizer::_get_property_list(List<PropertyInfo> *p_list) const {
+ AudioStream::_get_property_list(p_list); // Define the trivial scalar properties.
+ p_list->push_back(PropertyInfo(Variant::NIL, "Streams", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP));
+ for (int i = 0; i < audio_stream_pool.size(); i++) {
+ p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("stream_%d/stream", i), PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"));
+ p_list->push_back(PropertyInfo(Variant::FLOAT, vformat("stream_%d/weight", i), PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"));
+ }
}
-void AudioStreamRandomPitch::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_audio_stream", "stream"), &AudioStreamRandomPitch::set_audio_stream);
- ClassDB::bind_method(D_METHOD("get_audio_stream"), &AudioStreamRandomPitch::get_audio_stream);
+void AudioStreamRandomizer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_stream", "index"), &AudioStreamRandomizer::add_stream);
+ ClassDB::bind_method(D_METHOD("move_stream", "index_from", "index_to"), &AudioStreamRandomizer::move_stream);
+ ClassDB::bind_method(D_METHOD("remove_stream", "index"), &AudioStreamRandomizer::remove_stream);
+
+ ClassDB::bind_method(D_METHOD("set_stream", "index", "stream"), &AudioStreamRandomizer::set_stream);
+ ClassDB::bind_method(D_METHOD("get_stream", "index"), &AudioStreamRandomizer::get_stream);
+ ClassDB::bind_method(D_METHOD("set_stream_probability_weight", "index", "weight"), &AudioStreamRandomizer::set_stream_probability_weight);
+ ClassDB::bind_method(D_METHOD("get_stream_probability_weight", "index"), &AudioStreamRandomizer::get_stream_probability_weight);
+
+ ClassDB::bind_method(D_METHOD("set_streams_count", "count"), &AudioStreamRandomizer::set_streams_count);
+ ClassDB::bind_method(D_METHOD("get_streams_count"), &AudioStreamRandomizer::get_streams_count);
+
+ ClassDB::bind_method(D_METHOD("set_random_pitch", "scale"), &AudioStreamRandomizer::set_random_pitch);
+ ClassDB::bind_method(D_METHOD("get_random_pitch"), &AudioStreamRandomizer::get_random_pitch);
- ClassDB::bind_method(D_METHOD("set_random_pitch", "scale"), &AudioStreamRandomPitch::set_random_pitch);
- ClassDB::bind_method(D_METHOD("get_random_pitch"), &AudioStreamRandomPitch::get_random_pitch);
+ ClassDB::bind_method(D_METHOD("set_random_volume_offset_db", "db_offset"), &AudioStreamRandomizer::set_random_volume_offset_db);
+ ClassDB::bind_method(D_METHOD("get_random_volume_offset_db"), &AudioStreamRandomizer::get_random_volume_offset_db);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "audio_stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_audio_stream", "get_audio_stream");
+ ClassDB::bind_method(D_METHOD("set_playback_mode", "mode"), &AudioStreamRandomizer::set_playback_mode);
+ ClassDB::bind_method(D_METHOD("get_playback_mode"), &AudioStreamRandomizer::get_playback_mode);
+
+ ADD_ARRAY("streams", "stream_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "streams_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_streams_count", "get_streams_count");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_mode", PROPERTY_HINT_ENUM, "Random (Avoid Repeats),Random,Sequential"), "set_playback_mode", "get_playback_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "random_pitch", PROPERTY_HINT_RANGE, "1,16,0.01"), "set_random_pitch", "get_random_pitch");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "random_volume_offset_db", PROPERTY_HINT_RANGE, "0,40,0"), "set_random_volume_offset_db", "get_random_volume_offset_db");
+
+ BIND_ENUM_CONSTANT(PLAYBACK_RANDOM_NO_REPEATS);
+ BIND_ENUM_CONSTANT(PLAYBACK_RANDOM);
+ BIND_ENUM_CONSTANT(PLAYBACK_SEQUENTIAL);
}
-AudioStreamRandomPitch::AudioStreamRandomPitch() {
- random_pitch = 1.1;
+AudioStreamRandomizer::AudioStreamRandomizer() {
+ random_pitch_scale = 1.1;
+ random_volume_offset_db = 5;
}
-void AudioStreamPlaybackRandomPitch::start(float p_from_pos) {
+void AudioStreamPlaybackRandomizer::start(float p_from_pos) {
playing = playback;
- float range_from = 1.0 / random_pitch->random_pitch;
- float range_to = random_pitch->random_pitch;
+ {
+ float range_from = 1.0 / randomizer->random_pitch_scale;
+ float range_to = randomizer->random_pitch_scale;
- pitch_scale = range_from + Math::randf() * (range_to - range_from);
+ pitch_scale = range_from + Math::randf() * (range_to - range_from);
+ }
+ {
+ float range_from = -randomizer->random_volume_offset_db;
+ float range_to = randomizer->random_volume_offset_db;
+
+ float volume_offset_db = range_from + Math::randf() * (range_to - range_from);
+ volume_scale = Math::db2linear(volume_offset_db);
+ }
if (playing.is_valid()) {
playing->start(p_from_pos);
}
}
-void AudioStreamPlaybackRandomPitch::stop() {
+void AudioStreamPlaybackRandomizer::stop() {
if (playing.is_valid()) {
playing->stop();
- ;
}
}
-bool AudioStreamPlaybackRandomPitch::is_playing() const {
+bool AudioStreamPlaybackRandomizer::is_playing() const {
if (playing.is_valid()) {
return playing->is_playing();
}
@@ -452,7 +724,7 @@ bool AudioStreamPlaybackRandomPitch::is_playing() const {
return false;
}
-int AudioStreamPlaybackRandomPitch::get_loop_count() const {
+int AudioStreamPlaybackRandomizer::get_loop_count() const {
if (playing.is_valid()) {
return playing->get_loop_count();
}
@@ -460,7 +732,7 @@ int AudioStreamPlaybackRandomPitch::get_loop_count() const {
return 0;
}
-float AudioStreamPlaybackRandomPitch::get_playback_position() const {
+float AudioStreamPlaybackRandomizer::get_playback_position() const {
if (playing.is_valid()) {
return playing->get_playback_position();
}
@@ -468,13 +740,13 @@ float AudioStreamPlaybackRandomPitch::get_playback_position() const {
return 0;
}
-void AudioStreamPlaybackRandomPitch::seek(float p_time) {
+void AudioStreamPlaybackRandomizer::seek(float p_time) {
if (playing.is_valid()) {
playing->seek(p_time);
}
}
-int AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
+int AudioStreamPlaybackRandomizer::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
if (playing.is_valid()) {
return playing->mix(p_buffer, p_rate_scale * pitch_scale, p_frames);
} else {
@@ -485,7 +757,7 @@ int AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_buffer, float p_rate_scale
}
}
-AudioStreamPlaybackRandomPitch::~AudioStreamPlaybackRandomPitch() {
- random_pitch->playbacks.erase(this);
+AudioStreamPlaybackRandomizer::~AudioStreamPlaybackRandomizer() {
+ randomizer->playbacks.erase(this);
}
/////////////////////////////////////////////
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 32159e96ef..ce9bcabb9c 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -167,43 +167,86 @@ public:
//
-class AudioStreamPlaybackRandomPitch;
+class AudioStreamPlaybackRandomizer;
-class AudioStreamRandomPitch : public AudioStream {
- GDCLASS(AudioStreamRandomPitch, AudioStream);
- friend class AudioStreamPlaybackRandomPitch;
+class AudioStreamRandomizer : public AudioStream {
+ GDCLASS(AudioStreamRandomizer, AudioStream);
- Set<AudioStreamPlaybackRandomPitch *> playbacks;
- Ref<AudioStream> audio_stream;
- float random_pitch;
+public:
+ enum PlaybackMode {
+ PLAYBACK_RANDOM_NO_REPEATS,
+ PLAYBACK_RANDOM,
+ PLAYBACK_SEQUENTIAL,
+ };
+
+private:
+ friend class AudioStreamPlaybackRandomizer;
+
+ struct PoolEntry {
+ Ref<AudioStream> stream;
+ float weight;
+ };
+
+ Set<AudioStreamPlaybackRandomizer *> playbacks;
+ Vector<PoolEntry> audio_stream_pool;
+ float random_pitch_scale;
+ float random_volume_offset_db;
+
+ Ref<AudioStreamPlayback> instance_playback_random();
+ Ref<AudioStreamPlayback> instance_playback_no_repeats();
+ Ref<AudioStreamPlayback> instance_playback_sequential();
+
+ Ref<AudioStream> last_playback = nullptr;
+ PlaybackMode playback_mode = PLAYBACK_RANDOM_NO_REPEATS;
protected:
static void _bind_methods();
+ bool _set(const StringName &p_name, const Variant &p_value);
+ bool _get(const StringName &p_name, Variant &r_ret) const;
+ void _get_property_list(List<PropertyInfo> *p_list) const;
+
public:
- void set_audio_stream(const Ref<AudioStream> &p_audio_stream);
- Ref<AudioStream> get_audio_stream() const;
+ void add_stream(int p_index);
+ void move_stream(int p_index_from, int p_index_to);
+ void remove_stream(int p_index);
+
+ void set_stream(int p_index, Ref<AudioStream> p_stream);
+ Ref<AudioStream> get_stream(int p_index) const;
+ void set_stream_probability_weight(int p_index, float p_weight);
+ float get_stream_probability_weight(int p_index) const;
- void set_random_pitch(float p_pitch);
+ void set_streams_count(int p_count);
+ int get_streams_count() const;
+
+ void set_random_pitch(float p_pitch_scale);
float get_random_pitch() const;
+ void set_random_volume_offset_db(float p_volume_offset_db);
+ float get_random_volume_offset_db() const;
+
+ void set_playback_mode(PlaybackMode p_playback_mode);
+ PlaybackMode get_playback_mode() const;
+
virtual Ref<AudioStreamPlayback> instance_playback() override;
virtual String get_stream_name() const override;
virtual float get_length() const override; //if supported, otherwise return 0
virtual bool is_monophonic() const override;
- AudioStreamRandomPitch();
+ AudioStreamRandomizer();
};
-class AudioStreamPlaybackRandomPitch : public AudioStreamPlayback {
- GDCLASS(AudioStreamPlaybackRandomPitch, AudioStreamPlayback);
- friend class AudioStreamRandomPitch;
+class AudioStreamPlaybackRandomizer : public AudioStreamPlayback {
+ GDCLASS(AudioStreamPlaybackRandomizer, AudioStreamPlayback);
+ friend class AudioStreamRandomizer;
- Ref<AudioStreamRandomPitch> random_pitch;
+ Ref<AudioStreamRandomizer> randomizer;
Ref<AudioStreamPlayback> playback;
Ref<AudioStreamPlayback> playing;
+
float pitch_scale;
+ float volume_scale;
public:
virtual void start(float p_from_pos = 0.0) override;
@@ -217,7 +260,9 @@ public:
virtual int mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) override;
- ~AudioStreamPlaybackRandomPitch();
+ ~AudioStreamPlaybackRandomizer();
};
+VARIANT_ENUM_CAST(AudioStreamRandomizer::PlaybackMode);
+
#endif // AUDIO_STREAM_H
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_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index 3c53887931..ba2d257c0a 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -74,7 +74,7 @@
*
*****************************************************************************/
-void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata,int stride) {
+void SMBPitchShift::PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata,int stride) {
/*
@@ -85,19 +85,32 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
*/
double magn, phase, tmp, window, real, imag;
- double freqPerBin, expct;
- long i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
+ double freqPerBin, expct, reciprocalFftFrameSize;
+ int64_t i,k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
/* set up some handy variables */
fftFrameSize2 = fftFrameSize/2;
+ reciprocalFftFrameSize = 1./fftFrameSize;
stepSize = fftFrameSize/osamp;
- freqPerBin = sampleRate/(double)fftFrameSize;
- expct = 2.*Math_PI*(double)stepSize/(double)fftFrameSize;
+ freqPerBin = reciprocalFftFrameSize * sampleRate;
+ expct = Math_TAU * reciprocalFftFrameSize * stepSize;
inFifoLatency = fftFrameSize-stepSize;
- if (gRover == 0) { gRover = inFifoLatency;
-}
+ if (gRover == 0) {
+ gRover = inFifoLatency;
+ }
- /* initialize our static arrays */
+ // If pitchShift changes clear arrays to prevent some artifacts and quality loss.
+ if (lastPitchShift != pitchShift) {
+ lastPitchShift = pitchShift;
+ memset(gInFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
+ memset(gOutFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
+ memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
+ memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
+ memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
+ memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
+ memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(double));
+ memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(double));
+ }
/* main processing loop */
for (i = 0; i < numSampsToProcess; i++){
@@ -112,7 +125,7 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* do windowing and re,im interleave */
for (k = 0; k < fftFrameSize;k++) {
- window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5;
+ window = -.5*cos(Math_TAU * reciprocalFftFrameSize * k)+.5;
gFFTworksp[2*k] = gInFIFO[k] * window;
gFFTworksp[2*k+1] = 0.;
}
@@ -124,6 +137,7 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* this is the analysis step */
for (k = 0; k <= fftFrameSize2; k++) {
+
/* de-interlace FFT buffer */
real = gFFTworksp[2*k];
imag = gFFTworksp[2*k+1];
@@ -141,13 +155,15 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* map delta phase into +/- Pi interval */
qpd = tmp/Math_PI;
- if (qpd >= 0) { qpd += qpd&1;
- } else { qpd -= qpd&1;
-}
+ if (qpd >= 0) {
+ qpd += qpd&1;
+ } else {
+ qpd -= qpd&1;
+ }
tmp -= Math_PI*(double)qpd;
/* get deviation from bin frequency from the +/- Pi interval */
- tmp = osamp*tmp/(2.*Math_PI);
+ tmp = osamp*tmp/Math_TAU;
/* compute the k-th partials' true frequency */
tmp = (double)k*freqPerBin + tmp*freqPerBin;
@@ -160,8 +176,8 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* ***************** PROCESSING ******************* */
/* this does the actual pitch shifting */
- memset(gSynMagn, 0, fftFrameSize*sizeof(float));
- memset(gSynFreq, 0, fftFrameSize*sizeof(float));
+ memset(gSynMagn, 0, fftFrameSize*sizeof(double));
+ memset(gSynFreq, 0, fftFrameSize*sizeof(double));
for (k = 0; k <= fftFrameSize2; k++) {
index = k*pitchShift;
if (index <= fftFrameSize2) {
@@ -184,7 +200,7 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
tmp /= freqPerBin;
/* take osamp into account */
- tmp = 2.*Math_PI*tmp/osamp;
+ tmp = Math_TAU*tmp/osamp;
/* add the overlap phase advance back in */
tmp += (double)k*expct;
@@ -199,33 +215,35 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
}
/* zero negative frequencies */
- for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) { gFFTworksp[k] = 0.;
-}
+ for (k = fftFrameSize+2; k < 2*MAX_FRAME_LENGTH; k++) {
+ gFFTworksp[k] = 0.;
+ }
/* do inverse transform */
smbFft(gFFTworksp, fftFrameSize, 1);
/* do windowing and add to output accumulator */
for(k=0; k < fftFrameSize; k++) {
- window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5;
+ window = -.5*cos(Math_TAU * reciprocalFftFrameSize * k)+.5;
gOutputAccum[k] += 2.*window*gFFTworksp[2*k]/(fftFrameSize2*osamp);
}
- for (k = 0; k < stepSize; k++) { gOutFIFO[k] = gOutputAccum[k];
-}
+ for (k = 0; k < stepSize; k++) {
+ gOutFIFO[k] = gOutputAccum[k];
+ }
/* shift accumulator */
- memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float));
+ memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(double));
/* move input FIFO */
- for (k = 0; k < inFifoLatency; k++) { gInFIFO[k] = gInFIFO[k+stepSize];
-}
+ for (k = 0; k < inFifoLatency; k++) {
+ gInFIFO[k] = gInFIFO[k+stepSize];
+ }
}
}
}
-
-void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
+void SMBPitchShift::smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign)
/*
FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse)
Fills fftBuffer[0...2*fftFrameSize-1] with the Fourier transform of the
@@ -238,14 +256,16 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
of the frequencies of interest is in fftBuffer[0...fftFrameSize].
*/
{
- float wr, wi, arg, *p1, *p2, temp;
- float tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
- long i, bitm, j, le, le2, k;
+ double wr, wi, arg, *p1, *p2, temp;
+ double tr, ti, ur, ui, *p1r, *p1i, *p2r, *p2i;
+ int64_t i, bitm, j, le, le2, k, logN;
+ logN = (int64_t)(log(fftFrameSize) / log(2.) + .5);
for (i = 2; i < 2*fftFrameSize-2; i += 2) {
for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) {
- if (i & bitm) { j++;
-}
+ if (i & bitm) {
+ j++;
+ }
j <<= 1;
}
if (i < j) {
@@ -255,7 +275,8 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
*p1 = *p2; *p2 = temp;
}
}
- for (k = 0, le = 2; k < (long)(log((double)fftFrameSize)/log(2.)+.5); k++) {
+
+ for (k = 0, le = 2; k < logN; k++) {
le <<= 1;
le2 = le>>1;
ur = 1.0;
@@ -288,6 +309,14 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
float sample_rate = AudioServer::get_singleton()->get_mix_rate();
+ // For pitch_scale 1.0 it's cheaper to just pass samples without processing them.
+ if (Math::is_equal_approx(base->pitch_scale, 1.0f)) {
+ for (int i = 0; i < p_frame_count; i++) {
+ p_dst_frames[i] = p_src_frames[i];
+ }
+ return;
+ }
+
float *in_l = (float *)p_src_frames;
float *in_r = in_l + 1;
@@ -361,7 +390,4 @@ AudioEffectPitchShift::AudioEffectPitchShift() {
pitch_scale = 1.0;
oversampling = 4;
fft_size = FFT_SIZE_2048;
- wet = 0.0;
- dry = 0.0;
- filter = false;
}
diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h
index 0478d05ceb..23da61bb32 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.h
+++ b/servers/audio/effects/audio_effect_pitch_shift.h
@@ -40,31 +40,33 @@ class SMBPitchShift {
float gInFIFO[MAX_FRAME_LENGTH];
float gOutFIFO[MAX_FRAME_LENGTH];
- float gFFTworksp[2 * MAX_FRAME_LENGTH];
- float gLastPhase[MAX_FRAME_LENGTH / 2 + 1];
- float gSumPhase[MAX_FRAME_LENGTH / 2 + 1];
- float gOutputAccum[2 * MAX_FRAME_LENGTH];
- float gAnaFreq[MAX_FRAME_LENGTH];
- float gAnaMagn[MAX_FRAME_LENGTH];
- float gSynFreq[MAX_FRAME_LENGTH];
- float gSynMagn[MAX_FRAME_LENGTH];
- long gRover;
-
- void smbFft(float *fftBuffer, long fftFrameSize, long sign);
+ double gFFTworksp[2 * MAX_FRAME_LENGTH];
+ double gLastPhase[MAX_FRAME_LENGTH / 2 + 1];
+ double gSumPhase[MAX_FRAME_LENGTH / 2 + 1];
+ double gOutputAccum[2 * MAX_FRAME_LENGTH];
+ double gAnaFreq[MAX_FRAME_LENGTH];
+ double gAnaMagn[MAX_FRAME_LENGTH];
+ double gSynFreq[MAX_FRAME_LENGTH];
+ double gSynMagn[MAX_FRAME_LENGTH];
+ int64_t gRover;
+ float lastPitchShift;
+
+ void smbFft(double *fftBuffer, int64_t fftFrameSize, int64_t sign);
public:
- void PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize, long osamp, float sampleRate, float *indata, float *outdata, int stride);
+ void PitchShift(float pitchShift, int64_t numSampsToProcess, int64_t fftFrameSize, int64_t osamp, float sampleRate, float *indata, float *outdata, int stride);
SMBPitchShift() {
gRover = 0;
memset(gInFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
memset(gOutFIFO, 0, MAX_FRAME_LENGTH * sizeof(float));
- memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(float));
- memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(float));
- memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(float));
- memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(float));
- memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(float));
- memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(float));
+ memset(gFFTworksp, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
+ memset(gLastPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
+ memset(gSumPhase, 0, (MAX_FRAME_LENGTH / 2 + 1) * sizeof(double));
+ memset(gOutputAccum, 0, 2 * MAX_FRAME_LENGTH * sizeof(double));
+ memset(gAnaFreq, 0, MAX_FRAME_LENGTH * sizeof(double));
+ memset(gAnaMagn, 0, MAX_FRAME_LENGTH * sizeof(double));
+ lastPitchShift = 1.0;
}
};
@@ -101,9 +103,6 @@ public:
float pitch_scale;
int oversampling;
FFTSize fft_size;
- float wet;
- float dry;
- bool filter;
protected:
static void _bind_methods();
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_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/debugger/SCsub b/servers/debugger/SCsub
new file mode 100644
index 0000000000..86681f9c74
--- /dev/null
+++ b/servers/debugger/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/debugger/servers_debugger.cpp b/servers/debugger/servers_debugger.cpp
new file mode 100644
index 0000000000..d1391937d9
--- /dev/null
+++ b/servers/debugger/servers_debugger.cpp
@@ -0,0 +1,463 @@
+/*************************************************************************/
+/* servers_debugger.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 "servers_debugger.h"
+
+#include "core/config/project_settings.h"
+#include "core/debugger/engine_debugger.h"
+#include "core/debugger/engine_profiler.h"
+#include "core/io/marshalls.h"
+#include "servers/display_server.h"
+
+#define CHECK_SIZE(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() < (uint32_t)(expected), false, String("Malformed ") + what + " message from script debugger, message too short. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
+#define CHECK_END(arr, expected, what) ERR_FAIL_COND_V_MSG((uint32_t)arr.size() > (uint32_t)expected, false, String("Malformed ") + what + " message from script debugger, message too long. Expected size: " + itos(expected) + ", actual size: " + itos(arr.size()))
+
+Array ServersDebugger::ResourceUsage::serialize() {
+ infos.sort();
+
+ Array arr;
+ arr.push_back(infos.size() * 4);
+ for (const ResourceInfo &E : infos) {
+ arr.push_back(E.path);
+ arr.push_back(E.format);
+ arr.push_back(E.type);
+ arr.push_back(E.vram);
+ }
+ return arr;
+}
+
+bool ServersDebugger::ResourceUsage::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 1, "ResourceUsage");
+ uint32_t size = p_arr[0];
+ CHECK_SIZE(p_arr, size, "ResourceUsage");
+ int idx = 1;
+ for (uint32_t i = 0; i < size / 4; i++) {
+ ResourceInfo info;
+ info.path = p_arr[idx];
+ info.format = p_arr[idx + 1];
+ info.type = p_arr[idx + 2];
+ info.vram = p_arr[idx + 3];
+ infos.push_back(info);
+ }
+ CHECK_END(p_arr, idx, "ResourceUsage");
+ return true;
+}
+
+Array ServersDebugger::ScriptFunctionSignature::serialize() {
+ Array arr;
+ arr.push_back(name);
+ arr.push_back(id);
+ return arr;
+}
+
+bool ServersDebugger::ScriptFunctionSignature::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 2, "ScriptFunctionSignature");
+ name = p_arr[0];
+ id = p_arr[1];
+ CHECK_END(p_arr, 2, "ScriptFunctionSignature");
+ return true;
+}
+
+Array ServersDebugger::ServersProfilerFrame::serialize() {
+ Array arr;
+ arr.push_back(frame_number);
+ arr.push_back(frame_time);
+ arr.push_back(idle_time);
+ arr.push_back(physics_time);
+ arr.push_back(physics_frame_time);
+ arr.push_back(script_time);
+
+ arr.push_back(servers.size());
+ for (int i = 0; i < servers.size(); i++) {
+ ServerInfo &s = servers[i];
+ arr.push_back(s.name);
+ arr.push_back(s.functions.size() * 2);
+ for (int j = 0; j < s.functions.size(); j++) {
+ ServerFunctionInfo &f = s.functions[j];
+ arr.push_back(f.name);
+ arr.push_back(f.time);
+ }
+ }
+
+ arr.push_back(script_functions.size() * 4);
+ for (int i = 0; i < script_functions.size(); i++) {
+ arr.push_back(script_functions[i].sig_id);
+ arr.push_back(script_functions[i].call_count);
+ arr.push_back(script_functions[i].self_time);
+ arr.push_back(script_functions[i].total_time);
+ }
+ return arr;
+}
+
+bool ServersDebugger::ServersProfilerFrame::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 7, "ServersProfilerFrame");
+ frame_number = p_arr[0];
+ frame_time = p_arr[1];
+ idle_time = p_arr[2];
+ physics_time = p_arr[3];
+ physics_frame_time = p_arr[4];
+ script_time = p_arr[5];
+ int servers_size = p_arr[6];
+ int idx = 7;
+ while (servers_size) {
+ CHECK_SIZE(p_arr, idx + 2, "ServersProfilerFrame");
+ servers_size--;
+ ServerInfo si;
+ si.name = p_arr[idx];
+ int sub_data_size = p_arr[idx + 1];
+ idx += 2;
+ CHECK_SIZE(p_arr, idx + sub_data_size, "ServersProfilerFrame");
+ for (int j = 0; j < sub_data_size / 2; j++) {
+ ServerFunctionInfo sf;
+ sf.name = p_arr[idx];
+ sf.time = p_arr[idx + 1];
+ idx += 2;
+ si.functions.push_back(sf);
+ }
+ servers.push_back(si);
+ }
+ CHECK_SIZE(p_arr, idx + 1, "ServersProfilerFrame");
+ int func_size = p_arr[idx];
+ idx += 1;
+ CHECK_SIZE(p_arr, idx + func_size, "ServersProfilerFrame");
+ for (int i = 0; i < func_size / 4; i++) {
+ ScriptFunctionInfo fi;
+ fi.sig_id = p_arr[idx];
+ fi.call_count = p_arr[idx + 1];
+ fi.self_time = p_arr[idx + 2];
+ fi.total_time = p_arr[idx + 3];
+ script_functions.push_back(fi);
+ idx += 4;
+ }
+ CHECK_END(p_arr, idx, "ServersProfilerFrame");
+ return true;
+}
+
+Array ServersDebugger::VisualProfilerFrame::serialize() {
+ Array arr;
+ arr.push_back(frame_number);
+ arr.push_back(areas.size() * 3);
+ for (int i = 0; i < areas.size(); i++) {
+ arr.push_back(areas[i].name);
+ arr.push_back(areas[i].cpu_msec);
+ arr.push_back(areas[i].gpu_msec);
+ }
+ return arr;
+}
+
+bool ServersDebugger::VisualProfilerFrame::deserialize(const Array &p_arr) {
+ CHECK_SIZE(p_arr, 2, "VisualProfilerFrame");
+ frame_number = p_arr[0];
+ int size = p_arr[1];
+ CHECK_SIZE(p_arr, size, "VisualProfilerFrame");
+ int idx = 2;
+ areas.resize(size / 3);
+ RS::FrameProfileArea *w = areas.ptrw();
+ for (int i = 0; i < size / 3; i++) {
+ w[i].name = p_arr[idx];
+ w[i].cpu_msec = p_arr[idx + 1];
+ w[i].gpu_msec = p_arr[idx + 2];
+ idx += 3;
+ }
+ CHECK_END(p_arr, idx, "VisualProfilerFrame");
+ return true;
+}
+class ServersDebugger::ScriptsProfiler : public EngineProfiler {
+ typedef ServersDebugger::ScriptFunctionSignature FunctionSignature;
+ typedef ServersDebugger::ScriptFunctionInfo FunctionInfo;
+ struct ProfileInfoSort {
+ bool operator()(ScriptLanguage::ProfilingInfo *A, ScriptLanguage::ProfilingInfo *B) const {
+ return A->total_time < B->total_time;
+ }
+ };
+ Vector<ScriptLanguage::ProfilingInfo> info;
+ Vector<ScriptLanguage::ProfilingInfo *> ptrs;
+ Map<StringName, int> sig_map;
+ int max_frame_functions = 16;
+
+public:
+ void toggle(bool p_enable, const Array &p_opts) {
+ if (p_enable) {
+ sig_map.clear();
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->profiling_start();
+ }
+ if (p_opts.size() == 1 && p_opts[0].get_type() == Variant::INT) {
+ max_frame_functions = MAX(0, int(p_opts[0]));
+ }
+ } else {
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ ScriptServer::get_language(i)->profiling_stop();
+ }
+ }
+ }
+
+ void write_frame_data(Vector<FunctionInfo> &r_funcs, uint64_t &r_total, bool p_accumulated) {
+ int ofs = 0;
+ for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+ if (p_accumulated) {
+ ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&info.write[ofs], info.size() - ofs);
+ } else {
+ ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&info.write[ofs], info.size() - ofs);
+ }
+ }
+
+ for (int i = 0; i < ofs; i++) {
+ ptrs.write[i] = &info.write[i];
+ }
+
+ SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa;
+ sa.sort(ptrs.ptrw(), ofs);
+
+ int to_send = MIN(ofs, max_frame_functions);
+
+ // Check signatures first, and compute total time.
+ r_total = 0;
+ for (int i = 0; i < to_send; i++) {
+ if (!sig_map.has(ptrs[i]->signature)) {
+ int idx = sig_map.size();
+ FunctionSignature sig;
+ sig.name = ptrs[i]->signature;
+ sig.id = idx;
+ EngineDebugger::get_singleton()->send_message("servers:function_signature", sig.serialize());
+ sig_map[ptrs[i]->signature] = idx;
+ }
+ r_total += ptrs[i]->self_time;
+ }
+
+ // Send frame, script time, functions information then
+ r_funcs.resize(to_send);
+
+ FunctionInfo *w = r_funcs.ptrw();
+ for (int i = 0; i < to_send; i++) {
+ if (sig_map.has(ptrs[i]->signature)) {
+ w[i].sig_id = sig_map[ptrs[i]->signature];
+ }
+ w[i].call_count = ptrs[i]->call_count;
+ w[i].total_time = ptrs[i]->total_time / 1000000.0;
+ w[i].self_time = ptrs[i]->self_time / 1000000.0;
+ }
+ }
+
+ ScriptsProfiler() {
+ info.resize(GLOBAL_GET("debug/settings/profiler/max_functions"));
+ ptrs.resize(info.size());
+ }
+};
+
+class ServersDebugger::ServersProfiler : public EngineProfiler {
+ bool skip_profile_frame = false;
+ typedef ServersDebugger::ServerInfo ServerInfo;
+ typedef ServersDebugger::ServerFunctionInfo ServerFunctionInfo;
+
+ Map<StringName, ServerInfo> server_data;
+ ScriptsProfiler scripts_profiler;
+
+ double frame_time = 0;
+ double idle_time = 0;
+ double physics_time = 0;
+ double physics_frame_time = 0;
+
+ void _send_frame_data(bool p_final) {
+ ServersDebugger::ServersProfilerFrame frame;
+ frame.frame_number = Engine::get_singleton()->get_process_frames();
+ frame.frame_time = frame_time;
+ frame.idle_time = idle_time;
+ frame.physics_time = physics_time;
+ frame.physics_frame_time = physics_frame_time;
+ Map<StringName, ServerInfo>::Element *E = server_data.front();
+ while (E) {
+ if (!p_final) {
+ frame.servers.push_back(E->get());
+ }
+ E->get().functions.clear();
+ E = E->next();
+ }
+ uint64_t time = 0;
+ scripts_profiler.write_frame_data(frame.script_functions, time, p_final);
+ frame.script_time = USEC_TO_SEC(time);
+ if (skip_profile_frame) {
+ skip_profile_frame = false;
+ return;
+ }
+ if (p_final) {
+ EngineDebugger::get_singleton()->send_message("servers:profile_total", frame.serialize());
+ } else {
+ EngineDebugger::get_singleton()->send_message("servers:profile_frame", frame.serialize());
+ }
+ }
+
+public:
+ void toggle(bool p_enable, const Array &p_opts) {
+ skip_profile_frame = false;
+ if (p_enable) {
+ server_data.clear(); // Clear old profiling data.
+ } else {
+ _send_frame_data(true); // Send final frame.
+ }
+ scripts_profiler.toggle(p_enable, p_opts);
+ }
+
+ void add(const Array &p_data) {
+ String name = p_data[0];
+ if (!server_data.has(name)) {
+ ServerInfo info;
+ info.name = name;
+ server_data[name] = info;
+ }
+ ServerInfo &srv = server_data[name];
+
+ ServerFunctionInfo fi;
+ fi.name = p_data[1];
+ fi.time = p_data[2];
+ srv.functions.push_back(fi);
+ }
+
+ void tick(double p_frame_time, double p_idle_time, double p_physics_time, double p_physics_frame_time) {
+ frame_time = p_frame_time;
+ idle_time = p_idle_time;
+ physics_time = p_physics_time;
+ physics_frame_time = p_physics_frame_time;
+ _send_frame_data(false);
+ }
+
+ void skip_frame() {
+ skip_profile_frame = true;
+ }
+};
+
+class ServersDebugger::VisualProfiler : public EngineProfiler {
+ typedef ServersDebugger::ServerInfo ServerInfo;
+ typedef ServersDebugger::ServerFunctionInfo ServerFunctionInfo;
+
+ Map<StringName, ServerInfo> server_data;
+
+public:
+ void toggle(bool p_enable, const Array &p_opts) {
+ RS::get_singleton()->set_frame_profiling_enabled(p_enable);
+ }
+
+ void add(const Array &p_data) {}
+
+ void tick(double p_frame_time, double p_idle_time, double p_physics_time, double p_physics_frame_time) {
+ Vector<RS::FrameProfileArea> profile_areas = RS::get_singleton()->get_frame_profile();
+ ServersDebugger::VisualProfilerFrame frame;
+ if (!profile_areas.size()) {
+ return;
+ }
+
+ frame.frame_number = RS::get_singleton()->get_frame_profile_frame();
+ frame.areas.append_array(profile_areas);
+ EngineDebugger::get_singleton()->send_message("visual:profile_frame", frame.serialize());
+ }
+};
+
+ServersDebugger *ServersDebugger::singleton = nullptr;
+
+void ServersDebugger::initialize() {
+ if (EngineDebugger::is_active()) {
+ memnew(ServersDebugger);
+ }
+}
+
+void ServersDebugger::deinitialize() {
+ if (singleton) {
+ memdelete(singleton);
+ }
+}
+
+Error ServersDebugger::_capture(void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured) {
+ ERR_FAIL_COND_V(!singleton, ERR_BUG);
+ r_captured = true;
+ if (p_cmd == "memory") {
+ singleton->_send_resource_usage();
+ } else if (p_cmd == "draw") { // Forced redraw.
+ // For camera override to stay live when the game is paused from the editor.
+ double delta = 0.0;
+ if (singleton->last_draw_time) {
+ delta = (OS::get_singleton()->get_ticks_usec() - singleton->last_draw_time) / 1000000.0;
+ }
+ singleton->last_draw_time = OS::get_singleton()->get_ticks_usec();
+ RenderingServer::get_singleton()->sync();
+ if (RenderingServer::get_singleton()->has_changed()) {
+ RenderingServer::get_singleton()->draw(true, delta);
+ }
+ } else if (p_cmd == "foreground") {
+ singleton->last_draw_time = 0.0;
+ DisplayServer::get_singleton()->window_move_to_foreground();
+ singleton->servers_profiler->skip_frame();
+ } else {
+ r_captured = false;
+ }
+ return OK;
+}
+
+void ServersDebugger::_send_resource_usage() {
+ ServersDebugger::ResourceUsage usage;
+
+ List<RS::TextureInfo> tinfo;
+ RS::get_singleton()->texture_debug_usage(&tinfo);
+
+ for (const RS::TextureInfo &E : tinfo) {
+ ServersDebugger::ResourceInfo info;
+ info.path = E.path;
+ info.vram = E.bytes;
+ info.id = E.texture;
+ info.type = "Texture";
+ if (E.depth == 0) {
+ info.format = itos(E.width) + "x" + itos(E.height) + " " + Image::get_format_name(E.format);
+ } else {
+ info.format = itos(E.width) + "x" + itos(E.height) + "x" + itos(E.depth) + " " + Image::get_format_name(E.format);
+ }
+ usage.infos.push_back(info);
+ }
+
+ EngineDebugger::get_singleton()->send_message("servers:memory_usage", usage.serialize());
+}
+
+ServersDebugger::ServersDebugger() {
+ singleton = this;
+
+ // Generic servers profiler (audio/physics/...)
+ servers_profiler.instantiate();
+ servers_profiler->bind("servers");
+
+ // Visual Profiler (cpu/gpu times)
+ visual_profiler.instantiate();
+ visual_profiler->bind("visual");
+
+ EngineDebugger::Capture servers_cap(nullptr, &_capture);
+ EngineDebugger::register_message_capture("servers", servers_cap);
+}
+
+ServersDebugger::~ServersDebugger() {
+ EngineDebugger::unregister_message_capture("servers");
+ singleton = nullptr;
+}
diff --git a/servers/debugger/servers_debugger.h b/servers/debugger/servers_debugger.h
new file mode 100644
index 0000000000..d1c55dc690
--- /dev/null
+++ b/servers/debugger/servers_debugger.h
@@ -0,0 +1,132 @@
+/*************************************************************************/
+/* servers_debugger.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 SERVER_DEBUGGER_H
+#define SERVER_DEBUGGER_H
+
+#include "core/debugger/debugger_marshalls.h"
+
+#include "servers/rendering_server.h"
+
+class ServersDebugger {
+public:
+ // Memory usage
+ struct ResourceInfo {
+ String path;
+ String format;
+ String type;
+ RID id;
+ int vram = 0;
+ bool operator<(const ResourceInfo &p_img) const { return vram == p_img.vram ? id < p_img.id : vram > p_img.vram; }
+ };
+
+ struct ResourceUsage {
+ List<ResourceInfo> infos;
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+ // Script Profiler
+ struct ScriptFunctionSignature {
+ StringName name;
+ int id = -1;
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+ struct ScriptFunctionInfo {
+ StringName name;
+ int sig_id = -1;
+ int call_count = 0;
+ double self_time = 0;
+ double total_time = 0;
+ };
+
+ // Servers profiler
+ struct ServerFunctionInfo {
+ StringName name;
+ double time = 0;
+ };
+
+ struct ServerInfo {
+ StringName name;
+ List<ServerFunctionInfo> functions;
+ };
+
+ struct ServersProfilerFrame {
+ int frame_number = 0;
+ double frame_time = 0;
+ double idle_time = 0;
+ double physics_time = 0;
+ double physics_frame_time = 0;
+ double script_time = 0;
+ List<ServerInfo> servers;
+ Vector<ScriptFunctionInfo> script_functions;
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+ // Visual Profiler
+ struct VisualProfilerFrame {
+ uint64_t frame_number = 0;
+ Vector<RS::FrameProfileArea> areas;
+
+ Array serialize();
+ bool deserialize(const Array &p_arr);
+ };
+
+private:
+ class ScriptsProfiler;
+ class ServersProfiler;
+ class VisualProfiler;
+
+ double last_draw_time = 0.0;
+ Ref<ServersProfiler> servers_profiler;
+ Ref<VisualProfiler> visual_profiler;
+
+ static ServersDebugger *singleton;
+
+ static Error _capture(void *p_user, const String &p_cmd, const Array &p_data, bool &r_captured);
+
+ void _send_resource_usage();
+
+ ServersDebugger();
+
+public:
+ static void initialize();
+ static void deinitialize();
+
+ ~ServersDebugger();
+};
+
+#endif // SERVERS_DEBUGGER_H
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index d880df2a9b..58a51e3aea 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.");
}
@@ -436,6 +440,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 +451,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);
diff --git a/servers/display_server.h b/servers/display_server.h
index 19bb111094..81ac551f57 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;
@@ -277,6 +277,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_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..68dac67d21 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())) {
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_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..2490a2f506 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())) {
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 bf8b6379d2..f405dea770 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -56,6 +56,7 @@
#include "camera/camera_feed.h"
#include "camera_server.h"
#include "core/extension/native_extension_manager.h"
+#include "debugger/servers_debugger.h"
#include "display_server.h"
#include "navigation_server_2d.h"
#include "navigation_server_3d.h"
@@ -140,7 +141,7 @@ void register_server_types() {
GDREGISTER_CLASS(AudioStreamPlayback);
GDREGISTER_VIRTUAL_CLASS(AudioStreamPlaybackResampled);
GDREGISTER_CLASS(AudioStreamMicrophone);
- GDREGISTER_CLASS(AudioStreamRandomPitch);
+ GDREGISTER_CLASS(AudioStreamRandomizer);
GDREGISTER_VIRTUAL_CLASS(AudioEffect);
GDREGISTER_VIRTUAL_CLASS(AudioEffectInstance);
GDREGISTER_CLASS(AudioEffectEQ);
@@ -223,6 +224,8 @@ void register_server_types() {
GDREGISTER_CLASS(PhysicsTestMotionParameters3D);
GDREGISTER_CLASS(PhysicsTestMotionResult3D);
+ ServersDebugger::initialize();
+
// Physics 2D
GLOBAL_DEF(PhysicsServer2DManager::setting_property_name, "DEFAULT");
ProjectSettings::get_singleton()->set_custom_property_info(PhysicsServer2DManager::setting_property_name, PropertyInfo(Variant::STRING, PhysicsServer2DManager::setting_property_name, PROPERTY_HINT_ENUM, "DEFAULT"));
@@ -241,6 +244,8 @@ void register_server_types() {
}
void unregister_server_types() {
+ ServersDebugger::deinitialize();
+
NativeExtensionManager::get_singleton()->deinitialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SERVERS);
memdelete(shader_types);
diff --git a/servers/rendering/rasterizer_dummy.h b/servers/rendering/rasterizer_dummy.h
index 7032f3fb03..74c080660d 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 {}
@@ -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_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/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index 7183fd110f..f16a4b1d19 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -482,12 +482,11 @@ void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i
RD::get_singleton()->compute_list_end();
}
-void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) {
+void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst) {
ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer.");
memset(&copy.push_constant, 0, sizeof(CopyPushConstant));
- uint32_t base_flags = 0;
copy.push_constant.section[0] = p_region.position.x;
copy.push_constant.section[1] = p_region.position.y;
copy.push_constant.section[2] = p_region.size.width;
@@ -497,23 +496,12 @@ void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back
RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]);
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_uniform_set_from_image(p_back_texture), 3);
-
- copy.push_constant.flags = base_flags | COPY_FLAG_HORIZONTAL;
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
-
- RD::get_singleton()->compute_list_add_barrier(compute_list);
-
- //VERTICAL
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_back_texture), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3);
- copy.push_constant.flags = base_flags;
RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
+
RD::get_singleton()->compute_list_end();
}
@@ -2044,7 +2032,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;
@@ -2052,7 +2040,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));
@@ -2072,7 +2060,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;
@@ -2343,8 +2331,8 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
Vector<String> copy_modes;
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n");
- copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n");
- copy_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n");
+ copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n");
copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n");
copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n");
copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n");
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index 1a080756a8..f5e5b1ace7 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -899,7 +899,7 @@ public:
void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
- void gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst = false);
+ void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst = false);
void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false);
void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
void gaussian_glow_raster(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0);
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..d113fcd4f0 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -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()) {
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..a623af7533 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -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()) {
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 2f8ef696cd..606527ed24 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);
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..1a84bafbd0 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;
@@ -1894,7 +1894,6 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32
RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lighs");
update_cascades();
- ; //need cascades updated for this
SDFGIShader::Light lights[SDFGI::MAX_STATIC_LIGHTS];
uint32_t light_count[SDFGI::MAX_STATIC_LIGHTS];
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
index 5e55262798..25f0dca3b7 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
@@ -392,7 +392,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 +504,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 +536,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..948340f469 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();
@@ -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;
}
@@ -3397,6 +3363,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;
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 899d2d763d..09c828ba37 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;
@@ -981,7 +981,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 +1002,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..b44ae6cf8d 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) {
@@ -1040,8 +1066,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 +1148,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 145c4f902e..1473a92a1a 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -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();
@@ -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);
}
@@ -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
@@ -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, &copy_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));
@@ -7516,10 +7576,6 @@ void RendererStorageRD::_clear_render_target(RenderTarget *rt) {
if (rt->backbuffer.is_valid()) {
RD::get_singleton()->free(rt->backbuffer);
rt->backbuffer = RID();
- for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
- //just erase copies, since the rest are erased by dependency
- RD::get_singleton()->free(rt->backbuffer_mipmaps[i].mipmap_copy);
- }
rt->backbuffer_mipmaps.clear();
rt->backbuffer_uniform_set = RID(); //chain deleted
}
@@ -7636,7 +7692,9 @@ void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
tf.mipmaps = mipmaps_required;
rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RD::get_singleton()->set_resource_name(rt->backbuffer, "Render Target Back Buffer");
rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
+ RD::get_singleton()->set_resource_name(rt->backbuffer_mipmap0, "Back Buffer slice mipmap 0");
{
Vector<RID> fb_tex;
@@ -7651,23 +7709,10 @@ void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
}
//create mipmaps
for (uint32_t i = 1; i < mipmaps_required; i++) {
- RenderTarget::BackbufferMipmap mm;
- {
- mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
- }
-
- {
- Size2 mm_size = Image::get_image_mipmap_size(tf.width, tf.height, Image::FORMAT_RGBA8, i);
+ RID mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
+ RD::get_singleton()->set_resource_name(mipmap, "Back Buffer slice mip: " + itos(i));
- RD::TextureFormat mmtf = tf;
- mmtf.width = mm_size.width;
- mmtf.height = mm_size.height;
- mmtf.mipmaps = 1;
-
- mm.mipmap_copy = RD::get_singleton()->texture_create(mmtf, RD::TextureView());
- }
-
- rt->backbuffer_mipmaps.push_back(mm);
+ rt->backbuffer_mipmaps.push_back(mipmap);
}
}
@@ -8111,7 +8156,7 @@ void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, c
if (!p_gen_mipmaps) {
return;
}
-
+ RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps");
//then mipmap blur
RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
@@ -8121,10 +8166,11 @@ void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, c
region.size.x = MAX(1, region.size.x >> 1);
region.size.y = MAX(1, region.size.y >> 1);
- const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i];
- effects->gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true);
- prev_texture = mm.mipmap;
+ RID mipmap = rt->backbuffer_mipmaps[i];
+ effects->gaussian_blur(prev_texture, mipmap, region, true);
+ prev_texture = mipmap;
}
+ RD::get_singleton()->draw_command_end_label();
}
void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
@@ -8164,7 +8210,7 @@ void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_targe
return; //nothing to do
}
}
-
+ RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2");
//then mipmap blur
RID prev_texture = rt->backbuffer_mipmap0;
@@ -8174,10 +8220,11 @@ void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_targe
region.size.x = MAX(1, region.size.x >> 1);
region.size.y = MAX(1, region.size.y >> 1);
- const RenderTarget::BackbufferMipmap &mm = rt->backbuffer_mipmaps[i];
- effects->gaussian_blur(prev_texture, mm.mipmap, mm.mipmap_copy, region, true);
- prev_texture = mm.mipmap;
+ RID mipmap = rt->backbuffer_mipmaps[i];
+ effects->gaussian_blur(prev_texture, mipmap, region, true);
+ prev_texture = mipmap;
}
+ RD::get_singleton()->draw_command_end_label();
}
RID RendererStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) {
@@ -9943,6 +9990,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);
@@ -10047,17 +10099,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));
+ }
}
}
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index 43bbcf6520..33a3b8e229 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);
@@ -1169,12 +1178,7 @@ private:
RID backbuffer_fb;
RID backbuffer_mipmap0;
- struct BackbufferMipmap {
- RID mipmap;
- RID mipmap_copy;
- };
-
- Vector<BackbufferMipmap> backbuffer_mipmaps;
+ Vector<RID> backbuffer_mipmaps;
RID framebuffer_uniform_set;
RID backbuffer_uniform_set;
@@ -2167,6 +2171,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);
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 d4d0ed0f56..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;
@@ -61,7 +61,7 @@ layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buff
layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
#endif
-#ifdef MODE_GAUSSIAN_GLOW
+#ifdef MODE_GAUSSIAN_BLUR
shared vec4 local_cache[256];
shared vec4 temp_cache[128];
#endif
@@ -70,7 +70,7 @@ void main() {
// Pixel being shaded
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
-#ifndef MODE_GAUSSIAN_GLOW // Glow needs the extra threads
+#ifndef MODE_GAUSSIAN_BLUR // Gaussian blur needs the extra threads
if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing
return;
}
@@ -92,35 +92,11 @@ void main() {
#ifdef MODE_GAUSSIAN_BLUR
- //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
-
- if (bool(params.flags & FLAG_HORIZONTAL)) {
- ivec2 base_pos = (pos + params.section.xy) << 1;
- vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607;
- color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879;
- color += texelFetch(source_color, base_pos + ivec2(2, 0), 0) * 0.131514;
- color += texelFetch(source_color, base_pos + ivec2(3, 0), 0) * 0.071303;
- color += texelFetch(source_color, base_pos + ivec2(-1, 0), 0) * 0.189879;
- color += texelFetch(source_color, base_pos + ivec2(-2, 0), 0) * 0.131514;
- color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303;
- imageStore(dest_buffer, pos + params.target, color);
- } else {
- ivec2 base_pos = (pos + params.section.xy);
- vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774;
- color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477;
- color += texelFetch(source_color, base_pos + ivec2(0, 2), 0) * 0.06136;
- color += texelFetch(source_color, base_pos + ivec2(0, -1), 0) * 0.24477;
- color += texelFetch(source_color, base_pos + ivec2(0, -2), 0) * 0.06136;
- imageStore(dest_buffer, pos + params.target, color);
- }
-#endif
-
-#ifdef MODE_GAUSSIAN_GLOW
-
// First pass copy texture into 16x16 local memory for every 8x8 thread block
vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16;
+#ifdef MODE_GLOW
if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) {
vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
@@ -128,12 +104,15 @@ void main() {
local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5;
local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5;
local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5;
- } else {
+ } else
+#endif
+ {
local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0);
local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0);
local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0);
local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0);
}
+#ifdef MODE_GLOW
if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
// Tonemap initial samples to reduce weight of fireflies: https://graphicrants.blogspot.com/2013/12/tone-mapping.html
local_cache[dest_index] /= 1.0 + dot(local_cache[dest_index].rgb, vec3(0.299, 0.587, 0.114));
@@ -141,29 +120,33 @@ void main() {
local_cache[dest_index + 16] /= 1.0 + dot(local_cache[dest_index + 16].rgb, vec3(0.299, 0.587, 0.114));
local_cache[dest_index + 16 + 1] /= 1.0 + dot(local_cache[dest_index + 16 + 1].rgb, vec3(0.299, 0.587, 0.114));
}
-
+ const float kernel[4] = { 0.174938, 0.165569, 0.140367, 0.106595 };
+#else
+ // Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect.
+ const float kernel[4] = { 0.214607, 0.189879, 0.131514, 0.071303 };
+#endif
memoryBarrierShared();
barrier();
// Horizontal pass. Needs to copy into 8x16 chunk of local memory so vertical pass has full resolution
uint read_index = gl_LocalInvocationID.x + gl_LocalInvocationID.y * 32 + 4;
vec4 color_top = vec4(0.0);
- color_top += local_cache[read_index] * 0.174938;
- color_top += local_cache[read_index + 1] * 0.165569;
- color_top += local_cache[read_index + 2] * 0.140367;
- color_top += local_cache[read_index + 3] * 0.106595;
- color_top += local_cache[read_index - 1] * 0.165569;
- color_top += local_cache[read_index - 2] * 0.140367;
- color_top += local_cache[read_index - 3] * 0.106595;
+ color_top += local_cache[read_index] * kernel[0];
+ color_top += local_cache[read_index + 1] * kernel[1];
+ color_top += local_cache[read_index + 2] * kernel[2];
+ color_top += local_cache[read_index + 3] * kernel[3];
+ color_top += local_cache[read_index - 1] * kernel[1];
+ color_top += local_cache[read_index - 2] * kernel[2];
+ color_top += local_cache[read_index - 3] * kernel[3];
vec4 color_bottom = vec4(0.0);
- color_bottom += local_cache[read_index + 16] * 0.174938;
- color_bottom += local_cache[read_index + 1 + 16] * 0.165569;
- color_bottom += local_cache[read_index + 2 + 16] * 0.140367;
- color_bottom += local_cache[read_index + 3 + 16] * 0.106595;
- color_bottom += local_cache[read_index - 1 + 16] * 0.165569;
- color_bottom += local_cache[read_index - 2 + 16] * 0.140367;
- color_bottom += local_cache[read_index - 3 + 16] * 0.106595;
+ color_bottom += local_cache[read_index + 16] * kernel[0];
+ color_bottom += local_cache[read_index + 1 + 16] * kernel[1];
+ color_bottom += local_cache[read_index + 2 + 16] * kernel[2];
+ color_bottom += local_cache[read_index + 3 + 16] * kernel[3];
+ color_bottom += local_cache[read_index - 1 + 16] * kernel[1];
+ color_bottom += local_cache[read_index - 2 + 16] * kernel[2];
+ color_bottom += local_cache[read_index - 3 + 16] * kernel[3];
// rotate samples to take advantage of cache coherency
uint write_index = gl_LocalInvocationID.y * 2 + gl_LocalInvocationID.x * 16;
@@ -174,18 +157,24 @@ void main() {
memoryBarrierShared();
barrier();
+ // If destination outside of texture, can stop doing work now
+ if (any(greaterThanEqual(pos, params.section.zw))) {
+ return;
+ }
+
// Vertical pass
uint index = gl_LocalInvocationID.y + gl_LocalInvocationID.x * 16 + 4;
vec4 color = vec4(0.0);
- color += temp_cache[index] * 0.174938;
- color += temp_cache[index + 1] * 0.165569;
- color += temp_cache[index + 2] * 0.140367;
- color += temp_cache[index + 3] * 0.106595;
- color += temp_cache[index - 1] * 0.165569;
- color += temp_cache[index - 2] * 0.140367;
- color += temp_cache[index - 3] * 0.106595;
+ color += temp_cache[index] * kernel[0];
+ color += temp_cache[index + 1] * kernel[1];
+ color += temp_cache[index + 2] * kernel[2];
+ color += temp_cache[index + 3] * kernel[3];
+ color += temp_cache[index - 1] * kernel[1];
+ color += temp_cache[index - 2] * kernel[2];
+ color += temp_cache[index - 3] * kernel[3];
+#ifdef MODE_GLOW
if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
// Undo tonemap to restore range: https://graphicrants.blogspot.com/2013/12/tone-mapping.html
color /= 1.0 - dot(color.rgb, vec3(0.299, 0.587, 0.114));
@@ -205,7 +194,7 @@ void main() {
color = min(color * feedback, vec4(params.glow_luminance_cap));
}
-
+#endif
imageStore(dest_buffer, pos + params.target, color);
#endif
diff --git a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
index 8c68e2dc2f..2f1f9c4765 100644
--- a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
+++ b/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl
@@ -6,7 +6,7 @@
layout(location = 0) out vec2 uv_interp;
-layout(push_constant, binding = 1, std430) uniform Params {
+layout(push_constant, std430) uniform Params {
vec4 section;
vec2 pixel_size;
bool flip_y;
@@ -39,7 +39,7 @@ void main() {
#VERSION_DEFINES
-layout(push_constant, binding = 1, std430) uniform Params {
+layout(push_constant, std430) uniform Params {
vec4 section;
vec2 pixel_size;
bool flip_y;
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/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..5d65b00bee 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -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
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..16f77fb91a 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -877,17 +877,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;
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 fde5688301..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;
@@ -190,8 +190,7 @@ void main() {
}
vec2 final_pos;
- float grad;
- grad = steps_taken / float(params.num_steps);
+ float grad = (steps_taken + 1.0) / float(params.num_steps);
float initial_fade = params.curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), params.curve_fade_in);
float fade = pow(clamp(1.0 - grad, 0.0, 1.0), params.distance_fade) * initial_fade;
final_pos = pos;
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..5bda15236c 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
@@ -82,7 +82,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..b258e89c66 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;
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..7a0cea421e 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
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_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..5bdc7ce600 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -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..a2df7ad38e 100644
--- a/servers/rendering/renderer_storage.h
+++ b/servers/rendering/renderer_storage.h
@@ -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.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/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp
index 5b43ca4bcd..a0b0b31a7b 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;
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index b10022545c..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");
}
@@ -6495,9 +6496,17 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
decl.name = name;
#ifdef DEBUG_ENABLED
- if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG)) {
- if (p_block && p_block->parent_function) {
- StringName func_name = p_block->parent_function->name;
+ if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG) && p_block) {
+ FunctionNode *parent_function = nullptr;
+ {
+ BlockNode *block = p_block;
+ while (block && !block->parent_function) {
+ block = block->parent_block;
+ }
+ parent_function = block->parent_function;
+ }
+ if (parent_function) {
+ StringName func_name = parent_function->name;
if (!used_local_vars.has(func_name)) {
used_local_vars.insert(func_name, Map<StringName, Usage>());
@@ -7141,14 +7150,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
init_block->block_type = BlockNode::BLOCK_TYPE_FOR_INIT;
init_block->parent_block = p_block;
init_block->single_statement = true;
- // Need to find a parent function to correctly proceed unused variable warnings.
- {
- BlockNode *block = p_block;
- while (block && !block->parent_function) {
- block = block->parent_block;
- }
- init_block->parent_function = block->parent_function;
- }
cf->blocks.push_back(init_block);
Error err = _parse_block(init_block, p_function_info, true, false, false);
if (err != OK) {
@@ -7871,7 +7872,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (is_sampler_type(type)) {
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
- _set_error(vformat(RTR("Uniforms with '%s' qualifiers can't be of sampler type.", "instance")));
+ _set_error(vformat(RTR("The '%s' qualifier is not supported for sampler types."), "SCOPE_INSTANCE"));
return ERR_PARSE_ERROR;
}
uniform2.texture_order = texture_uniforms++;
@@ -7887,7 +7888,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
} else {
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
- _set_error(vformat(RTR("Uniforms with '%s' qualifier can't be of matrix type.", "instance")));
+ _set_error(vformat(RTR("The '%s' qualifier is not supported for matrix types."), "SCOPE_INSTANCE"));
return ERR_PARSE_ERROR;
}
uniform2.texture_order = -1;
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index b8bb211a7a..d628cf3713 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -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 584abbc351..820aeab5b7 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();
@@ -933,7 +933,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
}
- ERR_FAIL_COND_V_MSG((bsformat & RS::ARRAY_FORMAT_BLEND_SHAPE_MASK) != (format & RS::ARRAY_FORMAT_BLEND_SHAPE_MASK), ERR_INVALID_PARAMETER, "Blend shape format must match the main array format for Vertex, Normal and Tangent arrays.");
+ ERR_FAIL_COND_V_MSG(bsformat != (format & RS::ARRAY_FORMAT_BLEND_SHAPE_MASK), ERR_INVALID_PARAMETER, "Blend shape format must match the main array format for Vertex, Normal and Tangent arrays.");
}
}
@@ -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);
@@ -2830,12 +2830,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 +2860,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,7 +2872,7 @@ 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);
@@ -2979,7 +2979,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)"));
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 472fff1bf1..5e58afe718 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -259,7 +259,7 @@ public:
ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS,
ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX,
- ARRAY_FORMAT_BLEND_SHAPE_MASK = (~(ARRAY_FORMAT_COLOR | ARRAY_FORMAT_TEX_UV | ARRAY_FORMAT_TEX_UV2 | ARRAY_FORMAT_BONES | ARRAY_FORMAT_WEIGHTS | ARRAY_FORMAT_CUSTOM0 | ARRAY_FORMAT_CUSTOM1 | ARRAY_FORMAT_CUSTOM2 | ARRAY_FORMAT_CUSTOM3 | ARRAY_FORMAT_INDEX)) & 0x7FFFFFFF,
+ ARRAY_FORMAT_BLEND_SHAPE_MASK = ARRAY_FORMAT_VERTEX | ARRAY_FORMAT_NORMAL | ARRAY_FORMAT_TANGENT,
ARRAY_FORMAT_CUSTOM_BASE = (ARRAY_INDEX + 1),
ARRAY_FORMAT_CUSTOM_BITS = 3,
@@ -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 {
@@ -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..5792572dc1 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -85,6 +85,9 @@ 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_variation_coordinates, "font_rid", "variation_coordinates");
GDVIRTUAL_BIND(_font_get_variation_coordinates, "font_rid");
@@ -512,6 +515,18 @@ 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_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..d185e44806 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -134,6 +134,11 @@ 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_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..37cc6599b1 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -235,9 +235,12 @@ 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_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 +482,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);
diff --git a/servers/text_server.h b/servers/text_server.h
index 629a633b9f..38ad496490 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,9 @@ 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_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 +564,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_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp
index 62e011654e..7b21eeba04 100644
--- a/servers/xr/xr_positional_tracker.cpp
+++ b/servers/xr/xr_positional_tracker.cpp
@@ -149,7 +149,7 @@ void XRPositionalTracker::set_pose(const StringName &p_action_name, const Transf
new_pose->set_tracking_confidence(p_tracking_confidence);
poses[p_action_name] = new_pose;
- emit_signal("pose_changed", new_pose);
+ emit_signal(SNAME("pose_changed"), new_pose);
// TODO discuss whether we also want to create and emit an InputEventXRPose event
}
@@ -182,20 +182,20 @@ void XRPositionalTracker::set_input(const StringName &p_action_name, const Varia
case Variant::BOOL: {
bool pressed = p_value;
if (pressed) {
- emit_signal("button_pressed", p_action_name);
+ emit_signal(SNAME("button_pressed"), p_action_name);
} else {
- emit_signal("button_released", p_action_name);
+ emit_signal(SNAME("button_released"), p_action_name);
}
// TODO discuss whether we also want to create and emit an InputEventXRButton event
} break;
case Variant::FLOAT: {
- emit_signal("input_value_changed", p_action_name, p_value);
+ emit_signal(SNAME("input_value_changed"), p_action_name, p_value);
// TODO discuss whether we also want to create and emit an InputEventXRValue event
} break;
case Variant::VECTOR2: {
- emit_signal("input_axis_changed", p_action_name, p_value);
+ emit_signal(SNAME("input_axis_changed"), p_action_name, p_value);
// TODO discuss whether we also want to create and emit an InputEventXRAxis event
} break;