summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/audio/audio_stream.cpp23
-rw-r--r--servers/audio/audio_stream.h4
-rw-r--r--servers/audio/effects/audio_effect_amplify.cpp2
-rw-r--r--servers/audio/effects/audio_effect_capture.cpp2
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp40
-rw-r--r--servers/audio/effects/audio_effect_compressor.cpp4
-rw-r--r--servers/audio/effects/audio_effect_delay.cpp12
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp2
-rw-r--r--servers/audio/effects/audio_effect_filter.cpp2
-rw-r--r--servers/audio/effects/audio_effect_limiter.cpp6
-rw-r--r--servers/audio/effects/audio_effect_phaser.cpp6
-rw-r--r--servers/audio/effects/audio_effect_reverb.cpp2
-rw-r--r--servers/audio/effects/audio_effect_spectrum_analyzer.cpp2
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.cpp2
-rw-r--r--servers/audio/effects/audio_stream_generator.cpp4
-rw-r--r--servers/extensions/physics_server_3d_extension.cpp6
-rw-r--r--servers/extensions/physics_server_3d_extension.h6
-rw-r--r--servers/navigation_server_2d.cpp20
-rw-r--r--servers/navigation_server_2d.h14
-rw-r--r--servers/navigation_server_3d.cpp10
-rw-r--r--servers/navigation_server_3d.h14
-rw-r--r--servers/physics_2d/godot_area_2d.h4
-rw-r--r--servers/physics_2d/godot_physics_server_2d.cpp20
-rw-r--r--servers/physics_2d/godot_physics_server_2d.h2
-rw-r--r--servers/physics_2d/godot_space_2d.cpp4
-rw-r--r--servers/physics_2d/godot_space_2d.h4
-rw-r--r--servers/physics_2d/godot_step_2d.cpp4
-rw-r--r--servers/physics_3d/godot_area_3d.h4
-rw-r--r--servers/physics_3d/godot_physics_server_3d.cpp22
-rw-r--r--servers/physics_3d/godot_physics_server_3d.h2
-rw-r--r--servers/physics_3d/godot_soft_body_3d.cpp16
-rw-r--r--servers/physics_3d/godot_soft_body_3d.h6
-rw-r--r--servers/physics_3d/godot_space_3d.cpp4
-rw-r--r--servers/physics_3d/godot_space_3d.h4
-rw-r--r--servers/physics_3d/godot_step_3d.cpp8
-rw-r--r--servers/physics_server_2d.cpp18
-rw-r--r--servers/physics_server_2d.h14
-rw-r--r--servers/physics_server_3d.cpp18
-rw-r--r--servers/physics_server_3d.h14
-rw-r--r--servers/register_server_types.cpp4
-rw-r--r--servers/register_server_types.h1
-rw-r--r--servers/rendering/dummy/rasterizer_scene_dummy.h4
-rw-r--r--servers/rendering/dummy/storage/texture_storage.h3
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp24
-rw-r--r--servers/rendering/renderer_canvas_cull.h10
-rw-r--r--servers/rendering/renderer_canvas_render.cpp99
-rw-r--r--servers/rendering/renderer_canvas_render.h100
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp40
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h16
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp196
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h21
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp31
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h8
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp12
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h3
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp105
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h28
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp3
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp6
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/tonemap.glsl25
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl16
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl117
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl12
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl26
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl29
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl8
-rw-r--r--servers/rendering/renderer_rd/shaders/skeleton.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_blur.glsl20
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl1
-rw-r--r--servers/rendering/renderer_rd/shaders/ssil_interleave.glsl20
-rw-r--r--servers/rendering/renderer_rd/shaders/taa_resolve.glsl393
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl23
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp36
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.h4
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp12
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.h2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.cpp11
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.h2
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp14
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h7
-rw-r--r--servers/rendering/renderer_scene.h4
-rw-r--r--servers/rendering/renderer_scene_cull.cpp118
-rw-r--r--servers/rendering/renderer_scene_cull.h37
-rw-r--r--servers/rendering/renderer_scene_occlusion_cull.h22
-rw-r--r--servers/rendering/renderer_scene_render.cpp3
-rw-r--r--servers/rendering/renderer_scene_render.h7
-rw-r--r--servers/rendering/renderer_storage.h10
-rw-r--r--servers/rendering/renderer_viewport.cpp81
-rw-r--r--servers/rendering/renderer_viewport.h9
-rw-r--r--servers/rendering/rendering_server_default.cpp8
-rw-r--r--servers/rendering/rendering_server_default.h1
-rw-r--r--servers/rendering/shader_compiler.cpp9
-rw-r--r--servers/rendering/shader_compiler.h15
-rw-r--r--servers/rendering/shader_language.cpp1083
-rw-r--r--servers/rendering/shader_language.h35
-rw-r--r--servers/rendering/shader_types.cpp65
-rw-r--r--servers/rendering/shader_types.h4
-rw-r--r--servers/rendering/storage/texture_storage.h9
-rw-r--r--servers/rendering_server.cpp7
-rw-r--r--servers/rendering_server.h10
-rw-r--r--servers/text/text_server_extension.cpp25
-rw-r--r--servers/text/text_server_extension.h8
-rw-r--r--servers/text_server.cpp9
-rw-r--r--servers/text_server.h5
-rw-r--r--servers/xr_server.cpp4
106 files changed, 2231 insertions, 1208 deletions
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 9a9b9815ae..3983bc5cb1 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -387,9 +387,11 @@ void AudioStreamRandomizer::add_stream(int p_index) {
notify_property_list_changed();
}
+// p_index_to is relative to the array prior to the removal of from.
+// Example: [0, 1, 2, 3], move(1, 3) => [0, 2, 1, 3]
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_INDEX(p_index_from, audio_stream_pool.size());
+ // p_index_to == audio_stream_pool.size() is valid (move to end).
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]);
@@ -403,36 +405,31 @@ void AudioStreamRandomizer::move_stream(int p_index_from, int p_index_to) {
}
void AudioStreamRandomizer::remove_stream(int p_index) {
- ERR_FAIL_COND(p_index < 0);
- ERR_FAIL_COND(p_index >= audio_stream_pool.size());
+ ERR_FAIL_INDEX(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());
+ ERR_FAIL_INDEX(p_index, audio_stream_pool.size());
audio_stream_pool.write[p_index].stream = p_stream;
emit_signal(SNAME("changed"));
}
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);
+ ERR_FAIL_INDEX_V(p_index, audio_stream_pool.size(), nullptr);
return audio_stream_pool[p_index].stream;
}
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());
+ ERR_FAIL_INDEX(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);
+ ERR_FAIL_INDEX_V(p_index, audio_stream_pool.size(), 0);
return audio_stream_pool[p_index].weight;
}
@@ -702,7 +699,7 @@ void AudioStreamRandomizer::_bind_methods() {
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");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "random_volume_offset_db", PROPERTY_HINT_RANGE, "0,40,0,suffix:dB"), "set_random_volume_offset_db", "get_random_volume_offset_db");
BIND_ENUM_CONSTANT(PLAYBACK_RANDOM_NO_REPEATS);
BIND_ENUM_CONSTANT(PLAYBACK_RANDOM);
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 8851e1419b..bf200e7ecf 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -125,7 +125,7 @@ class AudioStreamMicrophone : public AudioStream {
GDCLASS(AudioStreamMicrophone, AudioStream);
friend class AudioStreamPlaybackMicrophone;
- RBSet<AudioStreamPlaybackMicrophone *> playbacks;
+ HashSet<AudioStreamPlaybackMicrophone *> playbacks;
protected:
static void _bind_methods();
@@ -192,7 +192,7 @@ private:
float weight;
};
- RBSet<AudioStreamPlaybackRandomizer *> playbacks;
+ HashSet<AudioStreamPlaybackRandomizer *> playbacks;
Vector<PoolEntry> audio_stream_pool;
float random_pitch_scale = 1.1f;
float random_volume_offset_db = 5.0f;
diff --git a/servers/audio/effects/audio_effect_amplify.cpp b/servers/audio/effects/audio_effect_amplify.cpp
index b01160ea5c..87d46f8bbe 100644
--- a/servers/audio/effects/audio_effect_amplify.cpp
+++ b/servers/audio/effects/audio_effect_amplify.cpp
@@ -64,7 +64,7 @@ void AudioEffectAmplify::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_volume_db", "volume"), &AudioEffectAmplify::set_volume_db);
ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioEffectAmplify::get_volume_db);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_volume_db", "get_volume_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01,suffix:dB"), "set_volume_db", "get_volume_db");
}
AudioEffectAmplify::AudioEffectAmplify() {
diff --git a/servers/audio/effects/audio_effect_capture.cpp b/servers/audio/effects/audio_effect_capture.cpp
index f605cfc9d4..1f5f5e259a 100644
--- a/servers/audio/effects/audio_effect_capture.cpp
+++ b/servers/audio/effects/audio_effect_capture.cpp
@@ -70,7 +70,7 @@ void AudioEffectCapture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_buffer_length_frames"), &AudioEffectCapture::get_buffer_length_frames);
ClassDB::bind_method(D_METHOD("get_pushed_frames"), &AudioEffectCapture::get_pushed_frames);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_buffer_length", "get_buffer_length");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01,suffix:s"), "set_buffer_length", "get_buffer_length");
}
Ref<AudioEffectInstance> AudioEffectCapture::instantiate() {
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp
index 8b1fe9cfd2..e5434eac02 100644
--- a/servers/audio/effects/audio_effect_chorus.cpp
+++ b/servers/audio/effects/audio_effect_chorus.cpp
@@ -313,32 +313,32 @@ void AudioEffectChorus::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dry", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dry", "get_dry");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wet", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_wet", "get_wet");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_voice_delay_ms", "get_voice_delay_ms", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01,suffix:ms"), "set_voice_delay_ms", "get_voice_delay_ms", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1,suffix:Hz"), "set_voice_rate_hz", "get_voice_rate_hz", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01,suffix:ms"), "set_voice_depth_ms", "get_voice_depth_ms", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1,suffix:dB"), "set_voice_level_db", "get_voice_level_db", 0);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 0);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/1/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 0);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_voice_delay_ms", "get_voice_delay_ms", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01,suffix:ms"), "set_voice_delay_ms", "get_voice_delay_ms", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1,suffix:Hz"), "set_voice_rate_hz", "get_voice_rate_hz", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01,suffix:ms"), "set_voice_depth_ms", "get_voice_depth_ms", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1,suffix:dB"), "set_voice_level_db", "get_voice_level_db", 1);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 1);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/2/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 1);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_voice_delay_ms", "get_voice_delay_ms", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01,suffix:ms"), "set_voice_delay_ms", "get_voice_delay_ms", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1,suffix:Hz"), "set_voice_rate_hz", "get_voice_rate_hz", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01,suffix:ms"), "set_voice_depth_ms", "get_voice_depth_ms", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1,suffix:dB"), "set_voice_level_db", "get_voice_level_db", 2);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 2);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/3/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 2);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_voice_delay_ms", "get_voice_delay_ms", 3);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 3);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 3);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 3);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 3);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01,suffix:ms"), "set_voice_delay_ms", "get_voice_delay_ms", 3);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1,suffix:Hz"), "set_voice_rate_hz", "get_voice_rate_hz", 3);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01,suffix:ms"), "set_voice_depth_ms", "get_voice_depth_ms", 3);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1,suffix:dB"), "set_voice_level_db", "get_voice_level_db", 3);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 3);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "voice/4/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 3);
}
diff --git a/servers/audio/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp
index f75d092dd3..ee71a6dba7 100644
--- a/servers/audio/effects/audio_effect_compressor.cpp
+++ b/servers/audio/effects/audio_effect_compressor.cpp
@@ -221,8 +221,8 @@ void AudioEffectCompressor::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "threshold", PROPERTY_HINT_RANGE, "-60,0,0.1"), "set_threshold", "get_threshold");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ratio", PROPERTY_HINT_RANGE, "1,48,0.1"), "set_ratio", "get_ratio");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gain", PROPERTY_HINT_RANGE, "-20,20,0.1"), "set_gain", "get_gain");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attack_us", PROPERTY_HINT_RANGE, "20,2000,1"), "set_attack_us", "get_attack_us");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "release_ms", PROPERTY_HINT_RANGE, "20,2000,1"), "set_release_ms", "get_release_ms");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "attack_us", PROPERTY_HINT_RANGE, U"20,2000,1,suffix:\u00B5s"), "set_attack_us", "get_attack_us");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "release_ms", PROPERTY_HINT_RANGE, "20,2000,1,suffix:ms"), "set_release_ms", "get_release_ms");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mix", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_mix", "get_mix");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "sidechain", PROPERTY_HINT_ENUM), "set_sidechain", "get_sidechain");
}
diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp
index 1909ab6eae..80e7a8223c 100644
--- a/servers/audio/effects/audio_effect_delay.cpp
+++ b/servers/audio/effects/audio_effect_delay.cpp
@@ -287,18 +287,18 @@ void AudioEffectDelay::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dry", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_dry", "get_dry");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tap1/active"), "set_tap1_active", "is_tap1_active");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap1/delay_ms", PROPERTY_HINT_RANGE, "0,1500,1"), "set_tap1_delay_ms", "get_tap1_delay_ms");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap1/level_db", PROPERTY_HINT_RANGE, "-60,0,0.01"), "set_tap1_level_db", "get_tap1_level_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap1/delay_ms", PROPERTY_HINT_RANGE, "0,1500,1,suffix:ms"), "set_tap1_delay_ms", "get_tap1_delay_ms");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap1/level_db", PROPERTY_HINT_RANGE, "-60,0,0.01,suffix:dB"), "set_tap1_level_db", "get_tap1_level_db");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap1/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_tap1_pan", "get_tap1_pan");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "tap2/active"), "set_tap2_active", "is_tap2_active");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap2/delay_ms", PROPERTY_HINT_RANGE, "0,1500,1"), "set_tap2_delay_ms", "get_tap2_delay_ms");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap2/level_db", PROPERTY_HINT_RANGE, "-60,0,0.01"), "set_tap2_level_db", "get_tap2_level_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap2/delay_ms", PROPERTY_HINT_RANGE, "0,1500,1,suffix:ms"), "set_tap2_delay_ms", "get_tap2_delay_ms");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap2/level_db", PROPERTY_HINT_RANGE, "-60,0,0.01,suffix:dB"), "set_tap2_level_db", "get_tap2_level_db");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap2/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_tap2_pan", "get_tap2_pan");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "feedback/active"), "set_feedback_active", "is_feedback_active");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "feedback/delay_ms", PROPERTY_HINT_RANGE, "0,1500,1"), "set_feedback_delay_ms", "get_feedback_delay_ms");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "feedback/level_db", PROPERTY_HINT_RANGE, "-60,0,0.01"), "set_feedback_level_db", "get_feedback_level_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "feedback/delay_ms", PROPERTY_HINT_RANGE, "0,1500,1,suffix:ms"), "set_feedback_delay_ms", "get_feedback_delay_ms");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "feedback/level_db", PROPERTY_HINT_RANGE, "-60,0,0.01,suffix:dB"), "set_feedback_level_db", "get_feedback_level_db");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "feedback/lowpass", PROPERTY_HINT_RANGE, "1,16000,1"), "set_feedback_lowpass", "get_feedback_lowpass");
}
diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp
index afc4353bd7..6820d796a4 100644
--- a/servers/audio/effects/audio_effect_distortion.cpp
+++ b/servers/audio/effects/audio_effect_distortion.cpp
@@ -161,7 +161,7 @@ void AudioEffectDistortion::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Clip,ATan,LoFi,Overdrive,Wave Shape"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pre_gain", PROPERTY_HINT_RANGE, "-60,60,0.01"), "set_pre_gain", "get_pre_gain");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "keep_hf_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_keep_hf_hz", "get_keep_hf_hz");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "keep_hf_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_keep_hf_hz", "get_keep_hf_hz");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "drive", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drive", "get_drive");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "post_gain", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_post_gain", "get_post_gain");
diff --git a/servers/audio/effects/audio_effect_filter.cpp b/servers/audio/effects/audio_effect_filter.cpp
index 06e66f22b1..a9409076cd 100644
--- a/servers/audio/effects/audio_effect_filter.cpp
+++ b/servers/audio/effects/audio_effect_filter.cpp
@@ -153,7 +153,7 @@ void AudioEffectFilter::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_db", "amount"), &AudioEffectFilter::set_db);
ClassDB::bind_method(D_METHOD("get_db"), &AudioEffectFilter::get_db);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_cutoff", "get_cutoff");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1,suffix:Hz"), "set_cutoff", "get_cutoff");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "resonance", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_resonance", "get_resonance");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gain", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_gain", "get_gain");
ADD_PROPERTY(PropertyInfo(Variant::INT, "db", PROPERTY_HINT_ENUM, "6 dB,12 dB,18 dB,24 dB"), "set_db", "get_db");
diff --git a/servers/audio/effects/audio_effect_limiter.cpp b/servers/audio/effects/audio_effect_limiter.cpp
index 5923cf8cf5..7bcd68d48b 100644
--- a/servers/audio/effects/audio_effect_limiter.cpp
+++ b/servers/audio/effects/audio_effect_limiter.cpp
@@ -120,9 +120,9 @@ void AudioEffectLimiter::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_soft_clip_ratio", "soft_clip"), &AudioEffectLimiter::set_soft_clip_ratio);
ClassDB::bind_method(D_METHOD("get_soft_clip_ratio"), &AudioEffectLimiter::get_soft_clip_ratio);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ceiling_db", PROPERTY_HINT_RANGE, "-20,-0.1,0.1"), "set_ceiling_db", "get_ceiling_db");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "threshold_db", PROPERTY_HINT_RANGE, "-30,0,0.1"), "set_threshold_db", "get_threshold_db");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "soft_clip_db", PROPERTY_HINT_RANGE, "0,6,0.1"), "set_soft_clip_db", "get_soft_clip_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ceiling_db", PROPERTY_HINT_RANGE, "-20,-0.1,0.1,suffix:dB"), "set_ceiling_db", "get_ceiling_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "threshold_db", PROPERTY_HINT_RANGE, "-30,0,0.1,suffix:dB"), "set_threshold_db", "get_threshold_db");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "soft_clip_db", PROPERTY_HINT_RANGE, "0,6,0.1,suffix:dB"), "set_soft_clip_db", "get_soft_clip_db");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "soft_clip_ratio", PROPERTY_HINT_RANGE, "3,20,0.1"), "set_soft_clip_ratio", "get_soft_clip_ratio");
}
diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp
index af5dce707e..2f86630ce9 100644
--- a/servers/audio/effects/audio_effect_phaser.cpp
+++ b/servers/audio/effects/audio_effect_phaser.cpp
@@ -144,9 +144,9 @@ void AudioEffectPhaser::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_depth", "depth"), &AudioEffectPhaser::set_depth);
ClassDB::bind_method(D_METHOD("get_depth"), &AudioEffectPhaser::get_depth);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_min_hz", PROPERTY_HINT_RANGE, "10,10000"), "set_range_min_hz", "get_range_min_hz");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_max_hz", PROPERTY_HINT_RANGE, "10,10000"), "set_range_max_hz", "get_range_max_hz");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rate_hz", PROPERTY_HINT_RANGE, "0.01,20"), "set_rate_hz", "get_rate_hz");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_min_hz", PROPERTY_HINT_RANGE, "10,10000,suffix:Hz"), "set_range_min_hz", "get_range_min_hz");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "range_max_hz", PROPERTY_HINT_RANGE, "10,10000,suffix:Hz"), "set_range_max_hz", "get_range_max_hz");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rate_hz", PROPERTY_HINT_RANGE, "0.01,20,suffix:Hz"), "set_rate_hz", "get_rate_hz");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "feedback", PROPERTY_HINT_RANGE, "0.1,0.9,0.1"), "set_feedback", "get_feedback");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "depth", PROPERTY_HINT_RANGE, "0.1,4,0.1"), "set_depth", "get_depth");
}
diff --git a/servers/audio/effects/audio_effect_reverb.cpp b/servers/audio/effects/audio_effect_reverb.cpp
index 0d4eb14e6a..bfc68152a4 100644
--- a/servers/audio/effects/audio_effect_reverb.cpp
+++ b/servers/audio/effects/audio_effect_reverb.cpp
@@ -176,7 +176,7 @@ void AudioEffectReverb::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_hpf"), &AudioEffectReverb::get_hpf);
ADD_GROUP("Predelay", "predelay_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "predelay_msec", PROPERTY_HINT_RANGE, "20,500,1"), "set_predelay_msec", "get_predelay_msec");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "predelay_msec", PROPERTY_HINT_RANGE, "20,500,1,suffix:ms"), "set_predelay_msec", "get_predelay_msec");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "predelay_feedback", PROPERTY_HINT_RANGE, "0,0.98,0.01"), "set_predelay_feedback", "get_predelay_feedback");
ADD_GROUP("", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "room_size", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_room_size", "get_room_size");
diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
index 10627be74c..30ebf626ae 100644
--- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
+++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
@@ -264,7 +264,7 @@ void AudioEffectSpectrumAnalyzer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_fft_size", "size"), &AudioEffectSpectrumAnalyzer::set_fft_size);
ClassDB::bind_method(D_METHOD("get_fft_size"), &AudioEffectSpectrumAnalyzer::get_fft_size);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.1,4,0.1"), "set_buffer_length", "get_buffer_length");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.1,4,0.1,suffix:s"), "set_buffer_length", "get_buffer_length");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "tap_back_pos", PROPERTY_HINT_RANGE, "0.1,4,0.1"), "set_tap_back_pos", "get_tap_back_pos");
ADD_PROPERTY(PropertyInfo(Variant::INT, "fft_size", PROPERTY_HINT_ENUM, "256,512,1024,2048,4096"), "set_fft_size", "get_fft_size");
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp
index 7bb62bcbed..e567add3e7 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.cpp
+++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp
@@ -138,7 +138,7 @@ void AudioEffectStereoEnhance::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_surround"), &AudioEffectStereoEnhance::get_surround);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pan_pullout", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_pan_pullout", "get_pan_pullout");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_pullout_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_time_pullout", "get_time_pullout");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_pullout_ms", PROPERTY_HINT_RANGE, "0,50,0.01,suffix:ms"), "set_time_pullout", "get_time_pullout");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "surround", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_surround", "get_surround");
}
diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp
index a3d615b925..46de1692e4 100644
--- a/servers/audio/effects/audio_stream_generator.cpp
+++ b/servers/audio/effects/audio_stream_generator.cpp
@@ -75,8 +75,8 @@ void AudioStreamGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_buffer_length", "seconds"), &AudioStreamGenerator::set_buffer_length);
ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioStreamGenerator::get_buffer_length);
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mix_rate", PROPERTY_HINT_RANGE, "20,192000,1"), "set_mix_rate", "get_mix_rate");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01"), "set_buffer_length", "get_buffer_length");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mix_rate", PROPERTY_HINT_RANGE, "20,192000,1,suffix:Hz"), "set_mix_rate", "get_mix_rate");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "buffer_length", PROPERTY_HINT_RANGE, "0.01,10,0.01,suffix:s"), "set_buffer_length", "get_buffer_length");
}
AudioStreamGenerator::AudioStreamGenerator() {
diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp
index b073e837e2..3694dcdb9a 100644
--- a/servers/extensions/physics_server_3d_extension.cpp
+++ b/servers/extensions/physics_server_3d_extension.cpp
@@ -34,7 +34,7 @@ bool PhysicsDirectSpaceState3DExtension::is_body_excluded_from_query(const RID &
return exclude && exclude->has(p_body);
}
-thread_local const RBSet<RID> *PhysicsDirectSpaceState3DExtension::exclude = nullptr;
+thread_local const HashSet<RID> *PhysicsDirectSpaceState3DExtension::exclude = nullptr;
void PhysicsDirectSpaceState3DExtension::_bind_methods() {
GDVIRTUAL_BIND(_intersect_ray, "from", "to", "collision_mask", "collide_with_bodies", "collide_with_areas", "hit_from_inside", "hit_back_faces", "result");
@@ -113,8 +113,8 @@ void PhysicsDirectBodyState3DExtension::_bind_methods() {
PhysicsDirectBodyState3DExtension::PhysicsDirectBodyState3DExtension() {
}
-thread_local const RBSet<RID> *PhysicsServer3DExtension::exclude_bodies = nullptr;
-thread_local const RBSet<ObjectID> *PhysicsServer3DExtension::exclude_objects = nullptr;
+thread_local const HashSet<RID> *PhysicsServer3DExtension::exclude_bodies = nullptr;
+thread_local const HashSet<ObjectID> *PhysicsServer3DExtension::exclude_objects = nullptr;
bool PhysicsServer3DExtension::body_test_motion_is_excluding_body(RID p_body) const {
return exclude_bodies && exclude_bodies->has(p_body);
diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h
index 8b49278306..663af1ae6c 100644
--- a/servers/extensions/physics_server_3d_extension.h
+++ b/servers/extensions/physics_server_3d_extension.h
@@ -122,7 +122,7 @@ GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionShapeRestInfo)
class PhysicsDirectSpaceState3DExtension : public PhysicsDirectSpaceState3D {
GDCLASS(PhysicsDirectSpaceState3DExtension, PhysicsDirectSpaceState3D);
- thread_local static const RBSet<RID> *exclude;
+ thread_local static const HashSet<RID> *exclude;
protected:
static void _bind_methods();
@@ -388,8 +388,8 @@ public:
GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, GDNativePtr<PhysicsServer3DExtensionMotionResult>)
- thread_local static const RBSet<RID> *exclude_bodies;
- thread_local static const RBSet<ObjectID> *exclude_objects;
+ thread_local static const HashSet<RID> *exclude_bodies;
+ thread_local static const HashSet<ObjectID> *exclude_objects;
bool body_test_motion_is_excluding_body(RID p_body) const;
bool body_test_motion_is_excluding_object(ObjectID p_object) const;
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index 901d335017..0442089503 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -166,7 +166,7 @@ void NavigationServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &NavigationServer2D::map_get_cell_size);
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer2D::map_set_edge_connection_margin);
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer2D::map_get_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "layers"), &NavigationServer2D::map_get_path, DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &NavigationServer2D::map_get_path, DEFVAL(1));
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer2D::map_get_closest_point);
ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer2D::map_get_closest_point_owner);
@@ -174,10 +174,14 @@ void NavigationServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer2D::map_get_agents);
ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create);
+ ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer2D::region_set_enter_cost);
+ ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer2D::region_get_enter_cost);
+ ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer2D::region_set_travel_cost);
+ ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer2D::region_get_travel_cost);
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer2D::region_set_map);
ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer2D::region_get_map);
- ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer2D::region_set_layers);
- ClassDB::bind_method(D_METHOD("region_get_layers", "region"), &NavigationServer2D::region_get_layers);
+ ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &NavigationServer2D::region_set_navigation_layers);
+ ClassDB::bind_method(D_METHOD("region_get_navigation_layers", "region"), &NavigationServer2D::region_get_navigation_layers);
ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer2D::region_set_transform);
ClassDB::bind_method(D_METHOD("region_set_navpoly", "region", "nav_poly"), &NavigationServer2D::region_set_navpoly);
ClassDB::bind_method(D_METHOD("region_get_connections_count", "region"), &NavigationServer2D::region_get_connections_count);
@@ -239,9 +243,15 @@ Vector2 FORWARD_2_R_C(v3_to_v2, map_get_closest_point, RID, p_map, const Vector2
RID FORWARD_2_C(map_get_closest_point_owner, RID, p_map, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
RID FORWARD_0_C(region_create);
+
+void FORWARD_2_C(region_set_enter_cost, RID, p_region, real_t, p_enter_cost, rid_to_rid, real_to_real);
+real_t FORWARD_1_C(region_get_enter_cost, RID, p_region, rid_to_rid);
+void FORWARD_2_C(region_set_travel_cost, RID, p_region, real_t, p_travel_cost, rid_to_rid, real_to_real);
+real_t FORWARD_1_C(region_get_travel_cost, RID, p_region, rid_to_rid);
+
void FORWARD_2_C(region_set_map, RID, p_region, RID, p_map, rid_to_rid, rid_to_rid);
-void FORWARD_2_C(region_set_layers, RID, p_region, uint32_t, p_layers, rid_to_rid, uint32_to_uint32);
-uint32_t FORWARD_1_C(region_get_layers, RID, p_region, rid_to_rid);
+void FORWARD_2_C(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32);
+uint32_t FORWARD_1_C(region_get_navigation_layers, RID, p_region, rid_to_rid);
void FORWARD_2_C(region_set_transform, RID, p_region, Transform2D, p_transform, rid_to_rid, trf2_to_trf3);
void NavigationServer2D::region_set_navpoly(RID p_region, Ref<NavigationPolygon> p_nav_mesh) const {
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index dfdcf5fca8..30f553d10b 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -75,7 +75,7 @@ public:
virtual real_t map_get_edge_connection_margin(RID p_map) const;
/// Returns the navigation path to reach the destination from the origin.
- virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_layers = 1) const;
+ virtual Vector<Vector2> map_get_path(RID p_map, Vector2 p_origin, Vector2 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const;
virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const;
virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const;
@@ -86,13 +86,21 @@ public:
/// Creates a new region.
virtual RID region_create() const;
+ /// Set the enter_cost of a region
+ virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) const;
+ virtual real_t region_get_enter_cost(RID p_region) const;
+
+ /// Set the travel_cost of a region
+ virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const;
+ virtual real_t region_get_travel_cost(RID p_region) const;
+
/// Set the map of this region.
virtual void region_set_map(RID p_region, RID p_map) const;
virtual RID region_get_map(RID p_region) const;
/// Set the region's layers
- virtual void region_set_layers(RID p_region, uint32_t p_layers) const;
- virtual uint32_t region_get_layers(RID p_region) const;
+ virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers) const;
+ virtual uint32_t region_get_navigation_layers(RID p_region) const;
/// Set the global transformation of this region.
virtual void region_set_transform(RID p_region, Transform2D p_transform) const;
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index 0ce869ad1a..60bbcec8d4 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -42,7 +42,7 @@ void NavigationServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_cell_size", "map"), &NavigationServer3D::map_get_cell_size);
ClassDB::bind_method(D_METHOD("map_set_edge_connection_margin", "map", "margin"), &NavigationServer3D::map_set_edge_connection_margin);
ClassDB::bind_method(D_METHOD("map_get_edge_connection_margin", "map"), &NavigationServer3D::map_get_edge_connection_margin);
- ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "layers"), &NavigationServer3D::map_get_path, DEFVAL(1));
+ ClassDB::bind_method(D_METHOD("map_get_path", "map", "origin", "destination", "optimize", "navigation_layers"), &NavigationServer3D::map_get_path, DEFVAL(1));
ClassDB::bind_method(D_METHOD("map_get_closest_point_to_segment", "map", "start", "end", "use_collision"), &NavigationServer3D::map_get_closest_point_to_segment, DEFVAL(false));
ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer3D::map_get_closest_point);
ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer3D::map_get_closest_point_normal);
@@ -52,10 +52,14 @@ void NavigationServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer3D::map_get_agents);
ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create);
+ ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer3D::region_set_enter_cost);
+ ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer3D::region_get_enter_cost);
+ ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer3D::region_set_travel_cost);
+ ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer3D::region_get_travel_cost);
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer3D::region_set_map);
ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer3D::region_get_map);
- ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer3D::region_set_layers);
- ClassDB::bind_method(D_METHOD("region_get_layers", "region"), &NavigationServer3D::region_get_layers);
+ ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &NavigationServer3D::region_set_navigation_layers);
+ ClassDB::bind_method(D_METHOD("region_get_navigation_layers", "region"), &NavigationServer3D::region_get_navigation_layers);
ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer3D::region_set_transform);
ClassDB::bind_method(D_METHOD("region_set_navmesh", "region", "nav_mesh"), &NavigationServer3D::region_set_navmesh);
ClassDB::bind_method(D_METHOD("region_bake_navmesh", "mesh", "node"), &NavigationServer3D::region_bake_navmesh);
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index c3d3a589a9..9c04d68622 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -84,7 +84,7 @@ public:
virtual real_t map_get_edge_connection_margin(RID p_map) const = 0;
/// Returns the navigation path to reach the destination from the origin.
- virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigable_layers = 1) const = 0;
+ virtual Vector<Vector3> map_get_path(RID p_map, Vector3 p_origin, Vector3 p_destination, bool p_optimize, uint32_t p_navigation_layers = 1) const = 0;
virtual Vector3 map_get_closest_point_to_segment(RID p_map, const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision = false) const = 0;
virtual Vector3 map_get_closest_point(RID p_map, const Vector3 &p_point) const = 0;
@@ -97,13 +97,21 @@ public:
/// Creates a new region.
virtual RID region_create() const = 0;
+ /// Set the enter_cost of a region
+ virtual void region_set_enter_cost(RID p_region, real_t p_enter_cost) const = 0;
+ virtual real_t region_get_enter_cost(RID p_region) const = 0;
+
+ /// Set the travel_cost of a region
+ virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const = 0;
+ virtual real_t region_get_travel_cost(RID p_region) const = 0;
+
/// Set the map of this region.
virtual void region_set_map(RID p_region, RID p_map) const = 0;
virtual RID region_get_map(RID p_region) const = 0;
/// Set the region's layers
- virtual void region_set_layers(RID p_region, uint32_t p_layers) const = 0;
- virtual uint32_t region_get_layers(RID p_region) const = 0;
+ virtual void region_set_navigation_layers(RID p_region, uint32_t p_navigation_layers) const = 0;
+ virtual uint32_t region_get_navigation_layers(RID p_region) const = 0;
/// Set the global transformation of this region.
virtual void region_set_transform(RID p_region, Transform3D p_transform) const = 0;
diff --git a/servers/physics_2d/godot_area_2d.h b/servers/physics_2d/godot_area_2d.h
index b825ea5cdb..35dad9d2c3 100644
--- a/servers/physics_2d/godot_area_2d.h
+++ b/servers/physics_2d/godot_area_2d.h
@@ -93,7 +93,7 @@ class GodotArea2D : public GodotCollisionObject2D {
HashMap<BodyKey, BodyState, BodyKey> monitored_bodies;
HashMap<BodyKey, BodyState, BodyKey> monitored_areas;
- RBSet<GodotConstraint2D *> constraints;
+ HashSet<GodotConstraint2D *> constraints;
virtual void _shapes_changed() override;
void _queue_monitor_update();
@@ -142,7 +142,7 @@ public:
_FORCE_INLINE_ void add_constraint(GodotConstraint2D *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(GodotConstraint2D *p_constraint) { constraints.erase(p_constraint); }
- _FORCE_INLINE_ const RBSet<GodotConstraint2D *> &get_constraints() const { return constraints; }
+ _FORCE_INLINE_ const HashSet<GodotConstraint2D *> &get_constraints() const { return constraints; }
_FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
void set_monitorable(bool p_monitorable);
diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp
index f82f2533f3..99e68de07c 100644
--- a/servers/physics_2d/godot_physics_server_2d.cpp
+++ b/servers/physics_2d/godot_physics_server_2d.cpp
@@ -1212,7 +1212,7 @@ void GodotPhysicsServer2D::free(RID p_rid) {
GodotSpace2D *space = space_owner.get_or_null(p_rid);
while (space->get_objects().size()) {
- GodotCollisionObject2D *co = static_cast<GodotCollisionObject2D *>(space->get_objects().front()->get());
+ GodotCollisionObject2D *co = static_cast<GodotCollisionObject2D *>(*space->get_objects().begin());
co->set_space(nullptr);
}
@@ -1250,11 +1250,11 @@ void GodotPhysicsServer2D::step(real_t p_step) {
island_count = 0;
active_objects = 0;
collision_pairs = 0;
- for (RBSet<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step(const_cast<GodotSpace2D *>(E->get()), p_step);
- island_count += E->get()->get_island_count();
- active_objects += E->get()->get_active_objects();
- collision_pairs += E->get()->get_collision_pairs();
+ for (const GodotSpace2D *E : active_spaces) {
+ stepper->step(const_cast<GodotSpace2D *>(E), p_step);
+ island_count += E->get_island_count();
+ active_objects += E->get_active_objects();
+ collision_pairs += E->get_collision_pairs();
}
}
@@ -1271,8 +1271,8 @@ void GodotPhysicsServer2D::flush_queries() {
uint64_t time_beg = OS::get_singleton()->get_ticks_usec();
- for (RBSet<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- GodotSpace2D *space = const_cast<GodotSpace2D *>(E->get());
+ for (const GodotSpace2D *E : active_spaces) {
+ GodotSpace2D *space = const_cast<GodotSpace2D *>(E);
space->call_queries();
}
@@ -1292,9 +1292,9 @@ void GodotPhysicsServer2D::flush_queries() {
total_time[i] = 0;
}
- for (RBSet<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) {
+ for (const GodotSpace2D *E : active_spaces) {
for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) {
- total_time[i] += E->get()->get_elapsed_time(GodotSpace2D::ElapsedTime(i));
+ total_time[i] += E->get_elapsed_time(GodotSpace2D::ElapsedTime(i));
}
}
diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h
index 55a7b39b9e..2af6e5c97c 100644
--- a/servers/physics_2d/godot_physics_server_2d.h
+++ b/servers/physics_2d/godot_physics_server_2d.h
@@ -56,7 +56,7 @@ class GodotPhysicsServer2D : public PhysicsServer2D {
bool flushing_queries = false;
GodotStep2D *stepper = nullptr;
- RBSet<const GodotSpace2D *> active_spaces;
+ HashSet<const GodotSpace2D *> active_spaces;
mutable RID_PtrOwner<GodotShape2D, true> shape_owner;
mutable RID_PtrOwner<GodotSpace2D, true> space_owner;
diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp
index 731eab2dfe..166ec3049e 100644
--- a/servers/physics_2d/godot_space_2d.cpp
+++ b/servers/physics_2d/godot_space_2d.cpp
@@ -874,7 +874,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D::
bool collided = false;
- if (recovered || (safe < 1)) {
+ if ((p_parameters.recovery_as_collision && recovered) || (safe < 1)) {
if (safe >= 1) {
best_shape = -1; //no best shape with cast, reset to -1
}
@@ -1073,7 +1073,7 @@ void GodotSpace2D::remove_object(GodotCollisionObject2D *p_object) {
objects.erase(p_object);
}
-const RBSet<GodotCollisionObject2D *> &GodotSpace2D::get_objects() const {
+const HashSet<GodotCollisionObject2D *> &GodotSpace2D::get_objects() const {
return objects;
}
diff --git a/servers/physics_2d/godot_space_2d.h b/servers/physics_2d/godot_space_2d.h
index e8b05fa4f9..b6fc48bd70 100644
--- a/servers/physics_2d/godot_space_2d.h
+++ b/servers/physics_2d/godot_space_2d.h
@@ -92,7 +92,7 @@ private:
static void *_broadphase_pair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_self);
static void _broadphase_unpair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_data, void *p_self);
- RBSet<GodotCollisionObject2D *> objects;
+ HashSet<GodotCollisionObject2D *> objects;
GodotArea2D *area = nullptr;
@@ -156,7 +156,7 @@ public:
void add_object(GodotCollisionObject2D *p_object);
void remove_object(GodotCollisionObject2D *p_object);
- const RBSet<GodotCollisionObject2D *> &get_objects() const;
+ const HashSet<GodotCollisionObject2D *> &get_objects() const;
_FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp
index 0df5c1aabc..551fd9329f 100644
--- a/servers/physics_2d/godot_step_2d.cpp
+++ b/servers/physics_2d/godot_step_2d.cpp
@@ -168,8 +168,8 @@ void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) {
const SelfList<GodotArea2D>::List &aml = p_space->get_moved_area_list();
while (aml.first()) {
- for (const RBSet<GodotConstraint2D *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) {
- GodotConstraint2D *constraint = E->get();
+ for (GodotConstraint2D *E : aml.first()->self()->get_constraints()) {
+ GodotConstraint2D *constraint = E;
if (constraint->get_island_step() == _step) {
continue;
}
diff --git a/servers/physics_3d/godot_area_3d.h b/servers/physics_3d/godot_area_3d.h
index 2a5e5a537a..a00451f602 100644
--- a/servers/physics_3d/godot_area_3d.h
+++ b/servers/physics_3d/godot_area_3d.h
@@ -99,7 +99,7 @@ class GodotArea3D : public GodotCollisionObject3D {
HashMap<BodyKey, BodyState, BodyKey> monitored_bodies;
HashMap<BodyKey, BodyState, BodyKey> monitored_areas;
- RBSet<GodotConstraint3D *> constraints;
+ HashSet<GodotConstraint3D *> constraints;
virtual void _shapes_changed() override;
void _queue_monitor_update();
@@ -163,7 +163,7 @@ public:
_FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraints.erase(p_constraint); }
- _FORCE_INLINE_ const RBSet<GodotConstraint3D *> &get_constraints() const { return constraints; }
+ _FORCE_INLINE_ const HashSet<GodotConstraint3D *> &get_constraints() const { return constraints; }
_FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
void set_monitorable(bool p_monitorable);
diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp
index cb4988757c..b735283ebe 100644
--- a/servers/physics_3d/godot_physics_server_3d.cpp
+++ b/servers/physics_3d/godot_physics_server_3d.cpp
@@ -1570,7 +1570,7 @@ void GodotPhysicsServer3D::free(RID p_rid) {
GodotSpace3D *space = space_owner.get_or_null(p_rid);
while (space->get_objects().size()) {
- GodotCollisionObject3D *co = static_cast<GodotCollisionObject3D *>(space->get_objects().front()->get());
+ GodotCollisionObject3D *co = static_cast<GodotCollisionObject3D *>(*space->get_objects().begin());
co->set_space(nullptr);
}
@@ -1611,11 +1611,11 @@ void GodotPhysicsServer3D::step(real_t p_step) {
island_count = 0;
active_objects = 0;
collision_pairs = 0;
- for (RBSet<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- stepper->step(const_cast<GodotSpace3D *>(E->get()), p_step);
- island_count += E->get()->get_island_count();
- active_objects += E->get()->get_active_objects();
- collision_pairs += E->get()->get_collision_pairs();
+ for (const GodotSpace3D *E : active_spaces) {
+ stepper->step(const_cast<GodotSpace3D *>(E), p_step);
+ island_count += E->get_island_count();
+ active_objects += E->get_active_objects();
+ collision_pairs += E->get_collision_pairs();
}
#endif
}
@@ -1635,8 +1635,8 @@ void GodotPhysicsServer3D::flush_queries() {
uint64_t time_beg = OS::get_singleton()->get_ticks_usec();
- for (RBSet<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) {
- GodotSpace3D *space = const_cast<GodotSpace3D *>(E->get());
+ for (const GodotSpace3D *E : active_spaces) {
+ GodotSpace3D *space = const_cast<GodotSpace3D *>(E);
space->call_queries();
}
@@ -1656,9 +1656,9 @@ void GodotPhysicsServer3D::flush_queries() {
total_time[i] = 0;
}
- for (RBSet<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) {
+ for (const GodotSpace3D *E : active_spaces) {
for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) {
- total_time[i] += E->get()->get_elapsed_time(GodotSpace3D::ElapsedTime(i));
+ total_time[i] += E->get_elapsed_time(GodotSpace3D::ElapsedTime(i));
}
}
@@ -1671,7 +1671,7 @@ void GodotPhysicsServer3D::flush_queries() {
values.push_back("flush_queries");
values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg));
- values.push_front("physics");
+ values.push_front("physics_3d");
EngineDebugger::profiler_add_frame_data("servers", values);
}
#endif
diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h
index 65c53084ac..1d57451925 100644
--- a/servers/physics_3d/godot_physics_server_3d.h
+++ b/servers/physics_3d/godot_physics_server_3d.h
@@ -54,7 +54,7 @@ class GodotPhysicsServer3D : public PhysicsServer3D {
bool flushing_queries = false;
GodotStep3D *stepper = nullptr;
- RBSet<const GodotSpace3D *> active_spaces;
+ HashSet<const GodotSpace3D *> active_spaces;
mutable RID_PtrOwner<GodotShape3D, true> shape_owner;
mutable RID_PtrOwner<GodotSpace3D, true> space_owner;
diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp
index 9cc7912a5a..173843072a 100644
--- a/servers/physics_3d/godot_soft_body_3d.cpp
+++ b/servers/physics_3d/godot_soft_body_3d.cpp
@@ -429,33 +429,33 @@ uint32_t GodotSoftBody3D::get_node_count() const {
}
real_t GodotSoftBody3D::get_node_inv_mass(uint32_t p_node_index) const {
- ERR_FAIL_COND_V(p_node_index >= nodes.size(), 0.0);
+ ERR_FAIL_UNSIGNED_INDEX_V(p_node_index, nodes.size(), 0.0);
return nodes[p_node_index].im;
}
Vector3 GodotSoftBody3D::get_node_position(uint32_t p_node_index) const {
- ERR_FAIL_COND_V(p_node_index >= nodes.size(), Vector3());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_node_index, nodes.size(), Vector3());
return nodes[p_node_index].x;
}
Vector3 GodotSoftBody3D::get_node_velocity(uint32_t p_node_index) const {
- ERR_FAIL_COND_V(p_node_index >= nodes.size(), Vector3());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_node_index, nodes.size(), Vector3());
return nodes[p_node_index].v;
}
Vector3 GodotSoftBody3D::get_node_biased_velocity(uint32_t p_node_index) const {
- ERR_FAIL_COND_V(p_node_index >= nodes.size(), Vector3());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_node_index, nodes.size(), Vector3());
return nodes[p_node_index].bv;
}
void GodotSoftBody3D::apply_node_impulse(uint32_t p_node_index, const Vector3 &p_impulse) {
- ERR_FAIL_COND(p_node_index >= nodes.size());
+ ERR_FAIL_UNSIGNED_INDEX(p_node_index, nodes.size());
Node &node = nodes[p_node_index];
node.v += p_impulse * node.im;
}
void GodotSoftBody3D::apply_node_bias_impulse(uint32_t p_node_index, const Vector3 &p_impulse) {
- ERR_FAIL_COND(p_node_index >= nodes.size());
+ ERR_FAIL_UNSIGNED_INDEX(p_node_index, nodes.size());
Node &node = nodes[p_node_index];
node.bv += p_impulse * node.im;
}
@@ -465,7 +465,7 @@ uint32_t GodotSoftBody3D::get_face_count() const {
}
void GodotSoftBody3D::get_face_points(uint32_t p_face_index, Vector3 &r_point_1, Vector3 &r_point_2, Vector3 &r_point_3) const {
- ERR_FAIL_COND(p_face_index >= faces.size());
+ ERR_FAIL_UNSIGNED_INDEX(p_face_index, faces.size());
const Face &face = faces[p_face_index];
r_point_1 = face.n[0]->x;
r_point_2 = face.n[1]->x;
@@ -473,7 +473,7 @@ void GodotSoftBody3D::get_face_points(uint32_t p_face_index, Vector3 &r_point_1,
}
Vector3 GodotSoftBody3D::get_face_normal(uint32_t p_face_index) const {
- ERR_FAIL_COND_V(p_face_index >= faces.size(), Vector3());
+ ERR_FAIL_UNSIGNED_INDEX_V(p_face_index, faces.size(), Vector3());
return faces[p_face_index].normal;
}
diff --git a/servers/physics_3d/godot_soft_body_3d.h b/servers/physics_3d/godot_soft_body_3d.h
index 094ab39c47..86f73c366b 100644
--- a/servers/physics_3d/godot_soft_body_3d.h
+++ b/servers/physics_3d/godot_soft_body_3d.h
@@ -37,8 +37,8 @@
#include "core/math/aabb.h"
#include "core/math/dynamic_bvh.h"
#include "core/math/vector3.h"
+#include "core/templates/hash_set.h"
#include "core/templates/local_vector.h"
-#include "core/templates/rb_set.h"
#include "core/templates/vset.h"
class GodotConstraint3D;
@@ -103,7 +103,7 @@ class GodotSoftBody3D : public GodotCollisionObject3D {
SelfList<GodotSoftBody3D> active_list;
- RBSet<GodotConstraint3D *> constraints;
+ HashSet<GodotConstraint3D *> constraints;
Vector<AreaCMP> areas;
@@ -123,7 +123,7 @@ public:
_FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraints.erase(p_constraint); }
- _FORCE_INLINE_ const RBSet<GodotConstraint3D *> &get_constraints() const { return constraints; }
+ _FORCE_INLINE_ const HashSet<GodotConstraint3D *> &get_constraints() const { return constraints; }
_FORCE_INLINE_ void clear_constraints() { constraints.clear(); }
_FORCE_INLINE_ void add_exception(const RID &p_exception) { exceptions.insert(p_exception); }
diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp
index 9c051b23f6..533d7605ce 100644
--- a/servers/physics_3d/godot_space_3d.cpp
+++ b/servers/physics_3d/godot_space_3d.cpp
@@ -906,7 +906,7 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D::
}
bool collided = false;
- if (recovered || (safe < 1)) {
+ if ((p_parameters.recovery_as_collision && recovered) || (safe < 1)) {
if (safe >= 1) {
best_shape = -1; //no best shape with cast, reset to -1
}
@@ -1096,7 +1096,7 @@ void GodotSpace3D::remove_object(GodotCollisionObject3D *p_object) {
objects.erase(p_object);
}
-const RBSet<GodotCollisionObject3D *> &GodotSpace3D::get_objects() const {
+const HashSet<GodotCollisionObject3D *> &GodotSpace3D::get_objects() const {
return objects;
}
diff --git a/servers/physics_3d/godot_space_3d.h b/servers/physics_3d/godot_space_3d.h
index 67dde30fb5..df7315e96d 100644
--- a/servers/physics_3d/godot_space_3d.h
+++ b/servers/physics_3d/godot_space_3d.h
@@ -89,7 +89,7 @@ private:
static void *_broadphase_pair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_self);
static void _broadphase_unpair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_data, void *p_self);
- RBSet<GodotCollisionObject3D *> objects;
+ HashSet<GodotCollisionObject3D *> objects;
GodotArea3D *area = nullptr;
@@ -158,7 +158,7 @@ public:
void add_object(GodotCollisionObject3D *p_object);
void remove_object(GodotCollisionObject3D *p_object);
- const RBSet<GodotCollisionObject3D *> &get_objects() const;
+ const HashSet<GodotCollisionObject3D *> &get_objects() const;
_FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; }
_FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; }
diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp
index b46436ba39..99656d01a0 100644
--- a/servers/physics_3d/godot_step_3d.cpp
+++ b/servers/physics_3d/godot_step_3d.cpp
@@ -87,8 +87,8 @@ void GodotStep3D::_populate_island(GodotBody3D *p_body, LocalVector<GodotBody3D
void GodotStep3D::_populate_island_soft_body(GodotSoftBody3D *p_soft_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island) {
p_soft_body->set_island_step(_step);
- for (RBSet<GodotConstraint3D *>::Element *E = p_soft_body->get_constraints().front(); E; E = E->next()) {
- GodotConstraint3D *constraint = const_cast<GodotConstraint3D *>(E->get());
+ for (const GodotConstraint3D *E : p_soft_body->get_constraints()) {
+ GodotConstraint3D *constraint = const_cast<GodotConstraint3D *>(E);
if (constraint->get_island_step() == _step) {
continue; // Already processed.
}
@@ -236,8 +236,8 @@ void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) {
const SelfList<GodotArea3D>::List &aml = p_space->get_moved_area_list();
while (aml.first()) {
- for (const RBSet<GodotConstraint3D *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) {
- GodotConstraint3D *constraint = E->get();
+ for (GodotConstraint3D *E : aml.first()->self()->get_constraints()) {
+ GodotConstraint3D *constraint = E;
if (constraint->get_island_step() == _step) {
continue;
}
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 4aeaa7497f..41aae36785 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -158,8 +158,8 @@ Vector<RID> PhysicsRayQueryParameters2D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
- for (RBSet<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
- ret.write[idx++] = E->get();
+ for (const RID &E : parameters.exclude) {
+ ret.write[idx++] = E;
}
return ret;
}
@@ -208,8 +208,8 @@ Vector<RID> PhysicsPointQueryParameters2D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
- for (RBSet<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
- ret.write[idx++] = E->get();
+ for (const RID &E : parameters.exclude) {
+ ret.write[idx++] = E;
}
return ret;
}
@@ -267,8 +267,8 @@ Vector<RID> PhysicsShapeQueryParameters2D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
- for (RBSet<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
- ret.write[idx++] = E->get();
+ for (const RID &E : parameters.exclude) {
+ ret.write[idx++] = E;
}
return ret;
}
@@ -505,12 +505,16 @@ void PhysicsTestMotionParameters2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_exclude_objects"), &PhysicsTestMotionParameters2D::get_exclude_objects);
ClassDB::bind_method(D_METHOD("set_exclude_objects", "exclude_list"), &PhysicsTestMotionParameters2D::set_exclude_objects);
+ ClassDB::bind_method(D_METHOD("is_recovery_as_collision_enabled"), &PhysicsTestMotionParameters2D::is_recovery_as_collision_enabled);
+ ClassDB::bind_method(D_METHOD("set_recovery_as_collision_enabled", "enabled"), &PhysicsTestMotionParameters2D::set_recovery_as_collision_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "from"), "set_from", "get_from");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude_bodies", "get_exclude_bodies");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recovery_as_collision"), "set_recovery_as_collision_enabled", "is_recovery_as_collision_enabled");
}
///////////////////////////////
@@ -857,7 +861,7 @@ PhysicsServer2D::~PhysicsServer2D() {
Vector<PhysicsServer2DManager::ClassInfo> PhysicsServer2DManager::physics_2d_servers;
int PhysicsServer2DManager::default_server_id = -1;
int PhysicsServer2DManager::default_server_priority = -1;
-const String PhysicsServer2DManager::setting_property_name("physics/2d/physics_engine");
+const String PhysicsServer2DManager::setting_property_name(PNAME("physics/2d/physics_engine"));
void PhysicsServer2DManager::on_servers_changed() {
String physics_servers("DEFAULT");
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index bd53764932..7a821c64e6 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -127,7 +127,7 @@ public:
struct RayParameters {
Vector2 from;
Vector2 to;
- RBSet<RID> exclude;
+ HashSet<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
@@ -157,7 +157,7 @@ public:
struct PointParameters {
Vector2 position;
ObjectID canvas_instance_id;
- RBSet<RID> exclude;
+ HashSet<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
@@ -173,7 +173,7 @@ public:
Transform2D transform;
Vector2 motion;
real_t margin = 0.0;
- RBSet<RID> exclude;
+ HashSet<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
@@ -483,8 +483,9 @@ public:
Vector2 motion;
real_t margin = 0.08;
bool collide_separation_ray = false;
- RBSet<RID> exclude_bodies;
- RBSet<ObjectID> exclude_objects;
+ HashSet<RID> exclude_bodies;
+ HashSet<ObjectID> exclude_objects;
+ bool recovery_as_collision = false;
MotionParameters() {}
@@ -727,6 +728,9 @@ public:
Array get_exclude_objects() const;
void set_exclude_objects(const Array &p_exclude);
+
+ bool is_recovery_as_collision_enabled() const { return parameters.recovery_as_collision; }
+ void set_recovery_as_collision_enabled(bool p_enabled) { parameters.recovery_as_collision = p_enabled; }
};
class PhysicsTestMotionResult2D : public RefCounted {
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index d05f5128b2..a606d055f7 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -177,8 +177,8 @@ Vector<RID> PhysicsRayQueryParameters3D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
- for (RBSet<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
- ret.write[idx++] = E->get();
+ for (const RID &E : parameters.exclude) {
+ ret.write[idx++] = E;
}
return ret;
}
@@ -231,8 +231,8 @@ Vector<RID> PhysicsPointQueryParameters3D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
- for (RBSet<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
- ret.write[idx++] = E->get();
+ for (const RID &E : parameters.exclude) {
+ ret.write[idx++] = E;
}
return ret;
}
@@ -286,8 +286,8 @@ Vector<RID> PhysicsShapeQueryParameters3D::get_exclude() const {
Vector<RID> ret;
ret.resize(parameters.exclude.size());
int idx = 0;
- for (RBSet<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) {
- ret.write[idx++] = E->get();
+ for (const RID &E : parameters.exclude) {
+ ret.write[idx++] = E;
}
return ret;
}
@@ -527,6 +527,9 @@ void PhysicsTestMotionParameters3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_exclude_objects"), &PhysicsTestMotionParameters3D::get_exclude_objects);
ClassDB::bind_method(D_METHOD("set_exclude_objects", "exclude_list"), &PhysicsTestMotionParameters3D::set_exclude_objects);
+ ClassDB::bind_method(D_METHOD("is_recovery_as_collision_enabled"), &PhysicsTestMotionParameters3D::is_recovery_as_collision_enabled);
+ ClassDB::bind_method(D_METHOD("set_recovery_as_collision_enabled", "enabled"), &PhysicsTestMotionParameters3D::set_recovery_as_collision_enabled);
+
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "from"), "set_from", "get_from");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion"), "set_motion", "get_motion");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin");
@@ -534,6 +537,7 @@ void PhysicsTestMotionParameters3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude_bodies", "get_exclude_bodies");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recovery_as_collision"), "set_recovery_as_collision_enabled", "is_recovery_as_collision_enabled");
}
///////////////////////////////
@@ -1029,7 +1033,7 @@ PhysicsServer3D::~PhysicsServer3D() {
Vector<PhysicsServer3DManager::ClassInfo> PhysicsServer3DManager::physics_servers;
int PhysicsServer3DManager::default_server_id = -1;
int PhysicsServer3DManager::default_server_priority = -1;
-const String PhysicsServer3DManager::setting_property_name("physics/3d/physics_engine");
+const String PhysicsServer3DManager::setting_property_name(PNAME("physics/3d/physics_engine"));
void PhysicsServer3DManager::on_servers_changed() {
String physics_servers2("DEFAULT");
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index c707f621b4..86a41d96ef 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -133,7 +133,7 @@ public:
struct RayParameters {
Vector3 from;
Vector3 to;
- RBSet<RID> exclude;
+ HashSet<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
@@ -165,7 +165,7 @@ public:
struct PointParameters {
Vector3 position;
- RBSet<RID> exclude;
+ HashSet<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
@@ -179,7 +179,7 @@ public:
Transform3D transform;
Vector3 motion;
real_t margin = 0.0;
- RBSet<RID> exclude;
+ HashSet<RID> exclude;
uint32_t collision_mask = UINT32_MAX;
bool collide_with_bodies = true;
@@ -520,8 +520,9 @@ public:
real_t margin = 0.001;
int max_collisions = 1;
bool collide_separation_ray = false;
- RBSet<RID> exclude_bodies;
- RBSet<ObjectID> exclude_objects;
+ HashSet<RID> exclude_bodies;
+ HashSet<ObjectID> exclude_objects;
+ bool recovery_as_collision = false;
MotionParameters() {}
@@ -941,6 +942,9 @@ public:
Array get_exclude_objects() const;
void set_exclude_objects(const Array &p_exclude);
+
+ bool is_recovery_as_collision_enabled() const { return parameters.recovery_as_collision; }
+ void set_recovery_as_collision_enabled(bool p_enabled) { parameters.recovery_as_collision = p_enabled; }
};
class PhysicsTestMotionResult3D : public RefCounted {
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 275a42a4e3..8bbe987cb7 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -107,7 +107,7 @@ static bool has_server_feature_callback(const String &p_feature) {
return false;
}
-void preregister_server_types() {
+void register_server_types() {
shader_types = memnew(ShaderTypes);
GDREGISTER_CLASS(TextServerManager);
@@ -119,9 +119,7 @@ void preregister_server_types() {
GDREGISTER_NATIVE_STRUCT(CaretInfo, "Rect2 leading_caret;Rect2 trailing_caret;TextServer::Direction leading_direction;TextServer::Direction trailing_direction");
Engine::get_singleton()->add_singleton(Engine::Singleton("TextServerManager", TextServerManager::get_singleton(), "TextServerManager"));
-}
-void register_server_types() {
OS::get_singleton()->set_has_server_feature_callback(has_server_feature_callback);
GDREGISTER_ABSTRACT_CLASS(DisplayServer);
diff --git a/servers/register_server_types.h b/servers/register_server_types.h
index cf6364eee3..32fd944bea 100644
--- a/servers/register_server_types.h
+++ b/servers/register_server_types.h
@@ -31,7 +31,6 @@
#ifndef REGISTER_SERVER_TYPES_H
#define REGISTER_SERVER_TYPES_H
-void preregister_server_types();
void register_server_types();
void unregister_server_types();
diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h
index fa58322ea8..e6d2b93f99 100644
--- a/servers/rendering/dummy/rasterizer_scene_dummy.h
+++ b/servers/rendering/dummy/rasterizer_scene_dummy.h
@@ -183,7 +183,7 @@ public:
void voxel_gi_set_quality(RS::VoxelGIQuality) override {}
- void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_info = nullptr) override {}
+ void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_info = nullptr) override {}
void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {}
void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {}
@@ -192,7 +192,7 @@ public:
void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) override {}
RID render_buffers_create() override { return RID(); }
- void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) override {}
+ void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override {}
void gi_set_use_half_resolution(bool p_enable) override {}
void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_curve) override {}
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index 534b9f07d8..11d827a6e3 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -152,7 +152,8 @@ public:
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override {}
virtual RID render_target_get_texture(RID p_render_target) override { return RID(); }
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override {}
- virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override {}
+ virtual void render_target_set_transparent(RID p_render_target, bool p_is_transparent) override {}
+ virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) override {}
virtual bool render_target_was_used(RID p_render_target) override { return false; }
virtual void render_target_set_as_unused(RID p_render_target) override {}
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index 46bc22ad54..bc1e8eb348 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -1831,8 +1831,8 @@ void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygo
RSG::canvas_render->occluder_polygon_set_shape(occluder_poly->occluder, p_shape, p_closed);
- for (RBSet<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) {
- E->get()->aabb_cache = occluder_poly->aabb;
+ for (RendererCanvasRender::LightOccluderInstance *E : occluder_poly->owners) {
+ E->aabb_cache = occluder_poly->aabb;
}
}
@@ -1841,8 +1841,8 @@ void RendererCanvasCull::canvas_occluder_polygon_set_cull_mode(RID p_occluder_po
ERR_FAIL_COND(!occluder_poly);
occluder_poly->cull_mode = p_mode;
RSG::canvas_render->occluder_polygon_set_cull_mode(occluder_poly->occluder, p_mode);
- for (RBSet<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) {
- E->get()->cull_cache = p_mode;
+ for (RendererCanvasRender::LightOccluderInstance *E : occluder_poly->owners) {
+ E->cull_cache = p_mode;
}
}
@@ -1928,26 +1928,26 @@ bool RendererCanvasCull::free(RID p_rid) {
ERR_FAIL_COND_V(!canvas, false);
while (canvas->viewports.size()) {
- RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.get_or_null(canvas->viewports.front()->get());
+ RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.get_or_null(*canvas->viewports.begin());
ERR_FAIL_COND_V(!vp, true);
HashMap<RID, RendererViewport::Viewport::CanvasData>::Iterator E = vp->canvas_map.find(p_rid);
ERR_FAIL_COND_V(!E, true);
vp->canvas_map.erase(p_rid);
- canvas->viewports.erase(canvas->viewports.front());
+ canvas->viewports.erase(*canvas->viewports.begin());
}
for (int i = 0; i < canvas->child_items.size(); i++) {
canvas->child_items[i].item->parent = RID();
}
- for (RBSet<RendererCanvasRender::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) {
- E->get()->canvas = RID();
+ for (RendererCanvasRender::Light *E : canvas->lights) {
+ E->canvas = RID();
}
- for (RBSet<RendererCanvasRender::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) {
- E->get()->canvas = RID();
+ for (RendererCanvasRender::LightOccluderInstance *E : canvas->occluders) {
+ E->canvas = RID();
}
canvas_owner.free(p_rid);
@@ -2030,8 +2030,8 @@ bool RendererCanvasCull::free(RID p_rid) {
RSG::canvas_render->free(occluder_poly->occluder);
while (occluder_poly->owners.size()) {
- occluder_poly->owners.front()->get()->polygon = RID();
- occluder_poly->owners.erase(occluder_poly->owners.front());
+ (*occluder_poly->owners.begin())->polygon = RID();
+ occluder_poly->owners.remove(occluder_poly->owners.begin());
}
canvas_light_occluder_polygon_owner.free(p_rid);
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index 6f3cd1d2c6..963cca7630 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -108,7 +108,7 @@ public:
Rect2 aabb;
RS::CanvasOccluderPolygonCullMode cull_mode;
RID occluder;
- RBSet<RendererCanvasRender::LightOccluderInstance *> owners;
+ HashSet<RendererCanvasRender::LightOccluderInstance *> owners;
LightOccluderPolygon() {
active = false;
@@ -121,7 +121,7 @@ public:
RID_Owner<RendererCanvasRender::LightOccluderInstance, true> canvas_light_occluder_owner;
struct Canvas : public RendererViewport::CanvasBase {
- RBSet<RID> viewports;
+ HashSet<RID> viewports;
struct ChildItem {
Point2 mirror;
Item *item = nullptr;
@@ -130,10 +130,10 @@ public:
}
};
- RBSet<RendererCanvasRender::Light *> lights;
- RBSet<RendererCanvasRender::Light *> directional_lights;
+ HashSet<RendererCanvasRender::Light *> lights;
+ HashSet<RendererCanvasRender::Light *> directional_lights;
- RBSet<RendererCanvasRender::LightOccluderInstance *> occluders;
+ HashSet<RendererCanvasRender::LightOccluderInstance *> occluders;
bool children_order_dirty;
Vector<ChildItem> child_items;
diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp
index 3b68cd74fd..163a24247e 100644
--- a/servers/rendering/renderer_canvas_render.cpp
+++ b/servers/rendering/renderer_canvas_render.cpp
@@ -29,3 +29,102 @@
/*************************************************************************/
#include "renderer_canvas_render.h"
+#include "servers/rendering/rendering_server_globals.h"
+
+const Rect2 &RendererCanvasRender::Item::get_rect() const {
+ if (custom_rect || (!rect_dirty && !update_when_visible)) {
+ return rect;
+ }
+
+ //must update rect
+
+ if (commands == nullptr) {
+ rect = Rect2();
+ rect_dirty = false;
+ return rect;
+ }
+
+ Transform2D xf;
+ bool found_xform = false;
+ bool first = true;
+
+ const Item::Command *c = commands;
+
+ while (c) {
+ Rect2 r;
+
+ switch (c->type) {
+ case Item::Command::TYPE_RECT: {
+ const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c);
+ r = crect->rect;
+
+ } break;
+ case Item::Command::TYPE_NINEPATCH: {
+ const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c);
+ r = style->rect;
+ } break;
+
+ case Item::Command::TYPE_POLYGON: {
+ const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
+ r = polygon->polygon.rect_cache;
+ } break;
+ case Item::Command::TYPE_PRIMITIVE: {
+ const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
+ for (uint32_t j = 0; j < primitive->point_count; j++) {
+ if (j == 0) {
+ r.position = primitive->points[0];
+ } else {
+ r.expand_to(primitive->points[j]);
+ }
+ }
+ } break;
+ case Item::Command::TYPE_MESH: {
+ const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
+ AABB aabb = RSG::mesh_storage->mesh_get_aabb(mesh->mesh, RID());
+
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+
+ } break;
+ case Item::Command::TYPE_MULTIMESH: {
+ const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c);
+ AABB aabb = RSG::mesh_storage->multimesh_get_aabb(multimesh->multimesh);
+
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+
+ } break;
+ case Item::Command::TYPE_PARTICLES: {
+ const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c);
+ if (particles_cmd->particles.is_valid()) {
+ AABB aabb = RSG::particles_storage->particles_get_aabb(particles_cmd->particles);
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
+ }
+
+ } break;
+ case Item::Command::TYPE_TRANSFORM: {
+ const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
+ xf = transform->xform;
+ found_xform = true;
+ [[fallthrough]];
+ }
+ default: {
+ c = c->next;
+ continue;
+ }
+ }
+
+ if (found_xform) {
+ r = xf.xform(r);
+ }
+
+ if (first) {
+ rect = r;
+ first = false;
+ } else {
+ rect = rect.merge(r);
+ }
+ c = c->next;
+ }
+
+ rect_dirty = false;
+ return rect;
+}
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
index 59cc3b7a92..1724a99b20 100644
--- a/servers/rendering/renderer_canvas_render.h
+++ b/servers/rendering/renderer_canvas_render.h
@@ -31,8 +31,6 @@
#ifndef RENDERINGSERVERCANVASRENDER_H
#define RENDERINGSERVERCANVASRENDER_H
-#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
#include "servers/rendering/renderer_storage.h"
class RendererCanvasRender {
@@ -356,103 +354,7 @@ public:
Rect2 global_rect_cache;
- const Rect2 &get_rect() const {
- if (custom_rect || (!rect_dirty && !update_when_visible)) {
- return rect;
- }
-
- //must update rect
-
- if (commands == nullptr) {
- rect = Rect2();
- rect_dirty = false;
- return rect;
- }
-
- Transform2D xf;
- bool found_xform = false;
- bool first = true;
-
- const Item::Command *c = commands;
-
- while (c) {
- Rect2 r;
-
- switch (c->type) {
- case Item::Command::TYPE_RECT: {
- const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c);
- r = crect->rect;
-
- } break;
- case Item::Command::TYPE_NINEPATCH: {
- const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c);
- r = style->rect;
- } break;
-
- case Item::Command::TYPE_POLYGON: {
- const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
- r = polygon->polygon.rect_cache;
- } break;
- case Item::Command::TYPE_PRIMITIVE: {
- const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
- for (uint32_t j = 0; j < primitive->point_count; j++) {
- if (j == 0) {
- r.position = primitive->points[0];
- } else {
- r.expand_to(primitive->points[j]);
- }
- }
- } break;
- case Item::Command::TYPE_MESH: {
- const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
- AABB aabb = RendererRD::MeshStorage::get_singleton()->mesh_get_aabb(mesh->mesh, RID());
-
- r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
-
- } break;
- case Item::Command::TYPE_MULTIMESH: {
- const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c);
- AABB aabb = RendererRD::MeshStorage::get_singleton()->multimesh_get_aabb(multimesh->multimesh);
-
- r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
-
- } break;
- case Item::Command::TYPE_PARTICLES: {
- const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c);
- if (particles_cmd->particles.is_valid()) {
- AABB aabb = RendererRD::ParticlesStorage::get_singleton()->particles_get_aabb(particles_cmd->particles);
- r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
- }
-
- } break;
- case Item::Command::TYPE_TRANSFORM: {
- const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
- xf = transform->xform;
- found_xform = true;
- [[fallthrough]];
- }
- default: {
- c = c->next;
- continue;
- }
- }
-
- if (found_xform) {
- r = xf.xform(r);
- }
-
- if (first) {
- rect = r;
- first = false;
- } else {
- rect = rect.merge(r);
- }
- c = c->next;
- }
-
- rect_dirty = false;
- return rect;
- }
+ const Rect2 &get_rect() const;
Command *commands = nullptr;
Command *last_command = nullptr;
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index 774745abdc..bf97c6fbe9 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -252,6 +252,35 @@ void EffectsRD::fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RI
RD::get_singleton()->compute_list_end(compute_list);
}
+void EffectsRD::taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity, RID p_prev_velocity, RID p_history, Size2 p_resolution, float p_z_near, float p_z_far) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+
+ RID shader = TAA_resolve.shader.version_get_shader(TAA_resolve.shader_version, 0);
+ ERR_FAIL_COND(shader.is_null());
+
+ memset(&TAA_resolve.push_constant, 0, sizeof(TAAResolvePushConstant));
+ TAA_resolve.push_constant.resolution_width = p_resolution.width;
+ TAA_resolve.push_constant.resolution_height = p_resolution.height;
+ TAA_resolve.push_constant.disocclusion_threshold = 0.025f;
+ TAA_resolve.push_constant.disocclusion_scale = 10.0f;
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, TAA_resolve.pipeline);
+
+ RD::Uniform u_frame_source(RD::UNIFORM_TYPE_IMAGE, 0, { p_frame });
+ RD::Uniform u_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, { default_sampler, p_depth });
+ RD::Uniform u_velocity(RD::UNIFORM_TYPE_IMAGE, 2, { p_velocity });
+ RD::Uniform u_prev_velocity(RD::UNIFORM_TYPE_IMAGE, 3, { p_prev_velocity });
+ RD::Uniform u_history(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 4, { default_sampler, p_history });
+ RD::Uniform u_frame_dest(RD::UNIFORM_TYPE_IMAGE, 5, { p_temp });
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_frame_source, u_depth, u_velocity, u_prev_velocity, u_history, u_frame_dest), 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &TAA_resolve.push_constant, sizeof(TAAResolvePushConstant));
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_resolution.width, p_resolution.height, 1);
+ RD::get_singleton()->compute_list_end();
+}
+
void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -415,7 +444,7 @@ void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_dept
}
void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) {
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>());
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, Vector<Color>());
if (p_reflection.is_valid()) {
if (p_base.is_valid()) {
@@ -2012,6 +2041,14 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
}
+ {
+ Vector<String> taa_modes;
+ taa_modes.push_back("\n#define MODE_TAA_RESOLVE");
+ TAA_resolve.shader.initialize(taa_modes);
+ TAA_resolve.shader_version = TAA_resolve.shader.version_create();
+ TAA_resolve.pipeline = RD::get_singleton()->compute_pipeline_create(TAA_resolve.shader.version_get_shader(TAA_resolve.shader_version, 0));
+ }
+
RD::SamplerState sampler;
sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
@@ -2060,6 +2097,7 @@ EffectsRD::~EffectsRD() {
RD::get_singleton()->free(filter.coefficient_buffer);
FSR_upscale.shader.version_free(FSR_upscale.shader_version);
+ TAA_resolve.shader.version_free(TAA_resolve.shader_version);
if (prefer_raster_effects) {
luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version);
roughness.raster_shader.version_free(roughness.shader_version);
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index 1963935236..787873642e 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -60,6 +60,7 @@
#include "servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/ssil_interleave.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/subsurface_scattering.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/taa_resolve.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
@@ -90,6 +91,20 @@ private:
RID pipeline;
} FSR_upscale;
+ struct TAAResolvePushConstant {
+ float resolution_width;
+ float resolution_height;
+ float disocclusion_threshold;
+ float disocclusion_scale;
+ };
+
+ struct TAAResolve {
+ TAAResolvePushConstant push_constant;
+ TaaResolveShaderRD shader;
+ RID shader_version;
+ RID pipeline;
+ } TAA_resolve;
+
struct CubemapRoughnessPushConstant {
uint32_t face_id;
uint32_t sample_count;
@@ -654,6 +669,7 @@ public:
bool get_prefer_raster_effects();
void fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness);
+ void taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity, RID p_prev_velocity, RID p_history, Size2 p_resolution, float p_z_near, float p_z_far);
void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
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 0eb981d51b..2d3998bd90 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -82,6 +82,27 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
}
}
+void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_velocity() {
+ if (!velocity_buffer.is_valid()) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R16G16_SFLOAT;
+ tf.width = width;
+ tf.height = height;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+
+ if (msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ RD::TextureFormat tf_aa = tf;
+ tf_aa.samples = texture_samples;
+ tf_aa.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ velocity_buffer_msaa = RD::get_singleton()->texture_create(tf_aa, RD::TextureView());
+
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ }
+
+ velocity_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ }
+}
+
void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() {
if (!voxelgi_buffer.is_valid()) {
RD::TextureFormat tf;
@@ -169,12 +190,23 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
if (!render_sdfgi_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_sdfgi_uniform_set)) {
RD::get_singleton()->free(render_sdfgi_uniform_set);
}
+
+ if (velocity_buffer != RID()) {
+ RD::get_singleton()->free(velocity_buffer);
+ velocity_buffer = RID();
+ }
+
+ if (velocity_buffer_msaa != RID()) {
+ RD::get_singleton()->free(velocity_buffer_msaa);
+ velocity_buffer_msaa = RID();
+ }
}
-void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
+void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count) {
clear();
msaa = p_msaa;
+ use_taa = p_use_taa;
width = p_width;
height = p_height;
@@ -260,6 +292,13 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_pass_fb(
fb.push_back(RID());
}
+ if (p_color_pass_flags & COLOR_PASS_FLAG_MOTION_VECTORS) {
+ ensure_velocity();
+ fb.push_back(use_msaa ? velocity_buffer_msaa : velocity_buffer);
+ } else {
+ fb.push_back(RID());
+ }
+
fb.push_back(use_msaa ? depth_msaa : depth);
int v_count = (p_color_pass_flags & COLOR_PASS_FLAG_MULTIVIEW) ? view_count : 1;
@@ -445,6 +484,10 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
pipeline_color_pass_flags |= SceneShaderForwardClustered::PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR;
}
+ if constexpr ((p_color_pass_flags & COLOR_PASS_FLAG_MOTION_VECTORS) != 0) {
+ pipeline_color_pass_flags |= SceneShaderForwardClustered::PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS;
+ }
+
if constexpr ((p_color_pass_flags & COLOR_PASS_FLAG_TRANSPARENT) != 0) {
pipeline_color_pass_flags |= SceneShaderForwardClustered::PIPELINE_COLOR_PASS_FLAG_TRANSPARENT;
}
@@ -567,9 +610,14 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis
switch (p_params->color_pass_flags) {
VALID_FLAG_COMBINATION(0);
VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT);
+ VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT | COLOR_PASS_FLAG_MULTIVIEW);
+ VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT | COLOR_PASS_FLAG_MOTION_VECTORS);
VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_SEPARATE_SPECULAR);
+ VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_SEPARATE_SPECULAR | COLOR_PASS_FLAG_MULTIVIEW);
+ VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_SEPARATE_SPECULAR | COLOR_PASS_FLAG_MOTION_VECTORS);
VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MULTIVIEW);
- VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT | COLOR_PASS_FLAG_MULTIVIEW);
+ VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MULTIVIEW | COLOR_PASS_FLAG_MOTION_VECTORS);
+ VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MOTION_VECTORS);
default: {
ERR_FAIL_MSG("Invalid color pass flag combination " + itos(p_params->color_pass_flags));
}
@@ -631,6 +679,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
CameraMatrix correction;
correction.set_depth_correction(p_flip_y);
+ correction.add_jitter_offset(p_render_data->taa_jitter);
CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
@@ -645,6 +694,9 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
}
+ scene_state.ubo.taa_jitter[0] = p_render_data->taa_jitter.x;
+ scene_state.ubo.taa_jitter[1] = p_render_data->taa_jitter.y;
+
scene_state.ubo.z_far = p_render_data->z_far;
scene_state.ubo.z_near = p_render_data->z_near;
@@ -708,61 +760,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
}
}
}
-#if 0
- if (p_render_data->render_buffers.is_valid() && render_buffers_is_sdfgi_enabled(p_render_data->render_buffers)) {
- scene_state.ubo.sdfgi_cascade_count = render_buffers_get_sdfgi_cascade_count(p_render_data->render_buffers);
- scene_state.ubo.sdfgi_probe_axis_size = render_buffers_get_sdfgi_cascade_probe_count(p_render_data->render_buffers);
- scene_state.ubo.sdfgi_cascade_probe_size[0] = scene_state.ubo.sdfgi_probe_axis_size - 1; //float version for performance
- scene_state.ubo.sdfgi_cascade_probe_size[1] = scene_state.ubo.sdfgi_probe_axis_size - 1;
- scene_state.ubo.sdfgi_cascade_probe_size[2] = scene_state.ubo.sdfgi_probe_axis_size - 1;
-
- float csize = render_buffers_get_sdfgi_cascade_size(p_render_data->render_buffers);
- scene_state.ubo.sdfgi_probe_to_uvw = 1.0 / float(scene_state.ubo.sdfgi_cascade_probe_size[0]);
- float occ_bias = 0.0;
- scene_state.ubo.sdfgi_occlusion_bias = occ_bias / csize;
- scene_state.ubo.sdfgi_use_occlusion = render_buffers_is_sdfgi_using_occlusion(p_render_data->render_buffers);
- scene_state.ubo.sdfgi_energy = render_buffers_get_sdfgi_energy(p_render_data->render_buffers);
-
- float cascade_voxel_size = (csize / scene_state.ubo.sdfgi_cascade_probe_size[0]);
- float occlusion_clamp = (cascade_voxel_size - 0.5) / cascade_voxel_size;
- scene_state.ubo.sdfgi_occlusion_clamp[0] = occlusion_clamp;
- scene_state.ubo.sdfgi_occlusion_clamp[1] = occlusion_clamp;
- scene_state.ubo.sdfgi_occlusion_clamp[2] = occlusion_clamp;
- scene_state.ubo.sdfgi_normal_bias = (render_buffers_get_sdfgi_normal_bias(p_render_data->render_buffers) / csize) * scene_state.ubo.sdfgi_cascade_probe_size[0];
-
- //vec2 tex_pixel_size = 1.0 / vec2(ivec2( (OCT_SIZE+2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE+2) * params.probe_axis_size ) );
- //vec3 probe_uv_offset = (ivec3(OCT_SIZE+2,OCT_SIZE+2,(OCT_SIZE+2) * params.probe_axis_size)) * tex_pixel_size.xyx;
-
- uint32_t oct_size = gi.sdfgi_get_lightprobe_octahedron_size();
-
- scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[0] = 1.0 / ((oct_size + 2) * scene_state.ubo.sdfgi_probe_axis_size * scene_state.ubo.sdfgi_probe_axis_size);
- scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[1] = 1.0 / ((oct_size + 2) * scene_state.ubo.sdfgi_probe_axis_size);
- scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[2] = 1.0;
-
- scene_state.ubo.sdfgi_probe_uv_offset[0] = float(oct_size + 2) * scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[0];
- scene_state.ubo.sdfgi_probe_uv_offset[1] = float(oct_size + 2) * scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[1];
- scene_state.ubo.sdfgi_probe_uv_offset[2] = float((oct_size + 2) * scene_state.ubo.sdfgi_probe_axis_size) * scene_state.ubo.sdfgi_lightprobe_tex_pixel_size[0];
-
- scene_state.ubo.sdfgi_occlusion_renormalize[0] = 0.5;
- scene_state.ubo.sdfgi_occlusion_renormalize[1] = 1.0;
- scene_state.ubo.sdfgi_occlusion_renormalize[2] = 1.0 / float(scene_state.ubo.sdfgi_cascade_count);
-
- for (uint32_t i = 0; i < scene_state.ubo.sdfgi_cascade_count; i++) {
- SceneState::UBO::SDFGICascade &c = scene_state.ubo.sdfgi_cascades[i];
- Vector3 pos = render_buffers_get_sdfgi_cascade_offset(p_render_data->render_buffers, i);
- pos -= p_render_data->cam_transform.origin; //make pos local to camera, to reduce numerical error
- c.position[0] = pos.x;
- c.position[1] = pos.y;
- c.position[2] = pos.z;
- c.to_probe = 1.0 / render_buffers_get_sdfgi_cascade_probe_size(p_render_data->render_buffers, i);
-
- Vector3i probe_ofs = render_buffers_get_sdfgi_cascade_probe_offset(p_render_data->render_buffers, i);
- c.probe_world_offset[0] = probe_ofs.x;
- c.probe_world_offset[1] = probe_ofs.y;
- c.probe_world_offset[2] = probe_ofs.z;
- }
- }
-#endif
+
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.ambient_light_color_energy[0] = 1;
@@ -862,14 +860,41 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount();
scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit();
+ if (p_render_data->render_buffers.is_valid()) {
+ RenderBufferDataForwardClustered *render_buffers = static_cast<RenderBufferDataForwardClustered *>(render_buffers_get_data(p_render_data->render_buffers));
+ if (render_buffers->use_taa || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
+ memcpy(&scene_state.prev_ubo, &scene_state.ubo, sizeof(SceneState::UBO));
+
+ CameraMatrix prev_correction;
+ prev_correction.set_depth_correction(true);
+ prev_correction.add_jitter_offset(p_render_data->prev_taa_jitter);
+ CameraMatrix prev_projection = prev_correction * p_render_data->prev_cam_projection;
+
+ //store camera into ubo
+ RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix);
+ RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix);
+ RendererStorageRD::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix);
+ RendererStorageRD::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix);
+
+ for (uint32_t v = 0; v < p_render_data->view_count; v++) {
+ prev_projection = prev_correction * p_render_data->view_projection[v];
+ RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]);
+ RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]);
+ }
+ scene_state.prev_ubo.taa_jitter[0] = p_render_data->prev_taa_jitter.x;
+ scene_state.prev_ubo.taa_jitter[1] = p_render_data->prev_taa_jitter.y;
+ scene_state.prev_ubo.time -= time_step;
+ }
+ }
+
if (p_index >= (int)scene_state.uniform_buffers.size()) {
uint32_t from = scene_state.uniform_buffers.size();
scene_state.uniform_buffers.resize(p_index + 1);
for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) {
- scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
+ scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO) * 2);
}
}
- RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER);
+ RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO) * 2, &scene_state.ubo_data, RD::BARRIER_MASK_RASTER);
}
void RenderForwardClustered::_update_instance_data_buffer(RenderListType p_render_list) {
@@ -895,6 +920,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i
if (p_render_info) {
p_render_info[RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += element_total;
}
+ uint64_t frame = RSG::rasterizer->get_frame_number();
uint32_t repeats = 0;
GeometryInstanceSurfaceDataCache *prev_surface = nullptr;
for (uint32_t i = 0; i < element_total; i++) {
@@ -903,10 +929,17 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i
SceneState::InstanceData &instance_data = scene_state.instance_data[p_render_list][i + p_offset];
+ if (inst->prev_transform_dirty && frame > inst->prev_transform_change_frame + 1 && inst->prev_transform_change_frame) {
+ inst->prev_transform = inst->transform;
+ inst->prev_transform_dirty = false;
+ }
+
if (inst->store_transform_cache) {
RendererStorageRD::store_transform(inst->transform, instance_data.transform);
+ RendererStorageRD::store_transform(inst->prev_transform, instance_data.prev_transform);
} else {
RendererStorageRD::store_transform(Transform3D(), instance_data.transform);
+ RendererStorageRD::store_transform(Transform3D(), instance_data.prev_transform);
}
instance_data.flags = inst->flags_cache;
@@ -1255,10 +1288,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Setup 3D Scene");
//scene_state.ubo.subsurface_scatter_width = subsurface_scatter_size;
-
- Vector2 vp_he = p_render_data->cam_projection.get_viewport_half_extents();
- scene_state.ubo.viewport_size[0] = vp_he.x;
- scene_state.ubo.viewport_size[1] = vp_he.y;
scene_state.ubo.directional_light_count = 0;
scene_state.ubo.opaque_prepass_threshold = 0.99f;
@@ -1281,6 +1310,10 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
screen_size.x = render_buffer->width;
screen_size.y = render_buffer->height;
+ if (render_buffer->use_taa || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
+ color_pass_flags |= COLOR_PASS_FLAG_MOTION_VECTORS;
+ }
+
if (p_render_data->voxel_gi_instances->size() > 0) {
using_voxelgi = true;
}
@@ -1350,6 +1383,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
ERR_FAIL(); //bug?
}
+ scene_state.ubo.viewport_size[0] = screen_size.x;
+ scene_state.ubo.viewport_size[1] = screen_size.y;
+
RD::get_singleton()->draw_command_begin_label("Render Setup");
_setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform);
@@ -1391,7 +1427,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
- if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
+ if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
@@ -1401,7 +1437,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
clear_color.r *= bg_energy;
clear_color.g *= bg_energy;
clear_color.b *= bg_energy;
- if (render_buffers_has_volumetric_fog(p_render_data->render_buffers) || environment_is_fog_enabled(p_render_data->environment)) {
+ if ((p_render_data->render_buffers.is_valid() && render_buffers_has_volumetric_fog(p_render_data->render_buffers)) || environment_is_fog_enabled(p_render_data->environment)) {
draw_sky_fog_only = true;
RendererRD::MaterialStorage::get_singleton()->material_set_param(sky.sky_scene_state.fog_material, "clear_color", Variant(clear_color.srgb_to_linear()));
}
@@ -1523,13 +1559,14 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
Vector<Color> c;
{
Color cc = clear_color.srgb_to_linear();
- if (using_separate_specular) {
+ if (using_separate_specular || render_buffer) {
cc.a = 0; //subsurf scatter must be 0
}
c.push_back(cc);
if (render_buffer) {
- c.push_back(Color(0, 0, 0, 0));
+ c.push_back(Color(0, 0, 0, 0)); // Separate specular
+ c.push_back(Color(0, 0, 0, 0)); // Motion vectors
}
}
@@ -1642,7 +1679,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
{
- uint32_t transparent_color_pass_flags = (color_pass_flags | COLOR_PASS_FLAG_TRANSPARENT) & ~COLOR_PASS_FLAG_SEPARATE_SPECULAR;
+ uint32_t transparent_color_pass_flags = (color_pass_flags | COLOR_PASS_FLAG_TRANSPARENT) & ~(COLOR_PASS_FLAG_SEPARATE_SPECULAR);
RID alpha_framebuffer = render_buffer ? render_buffer->get_color_pass_fb(transparent_color_pass_flags) : color_only_framebuffer;
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR, transparent_color_pass_flags, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
@@ -1656,6 +1693,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color);
+ if (render_buffer->use_taa) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->velocity_buffer_msaa, render_buffer->velocity_buffer);
+ }
storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
}
@@ -1668,6 +1708,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
RD::get_singleton()->draw_command_end_label();
+ if (render_buffer && render_buffer->use_taa) {
+ RENDER_TIMESTAMP("TAA")
+ _process_taa(p_render_data->render_buffers, render_buffer->velocity_buffer, p_render_data->z_near, p_render_data->z_far);
+ }
+
if (p_render_data->render_buffers.is_valid()) {
_debug_draw_cluster(p_render_data->render_buffers);
@@ -2594,7 +2639,13 @@ RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_te
RID RenderForwardClustered::_render_buffers_get_normal_texture(RID p_render_buffers) {
RenderBufferDataForwardClustered *rb = static_cast<RenderBufferDataForwardClustered *>(render_buffers_get_data(p_render_buffers));
- return rb->normal_roughness_buffer;
+ return rb->msaa == RS::VIEWPORT_MSAA_DISABLED ? rb->normal_roughness_buffer : rb->normal_roughness_buffer_msaa;
+}
+
+RID RenderForwardClustered::_render_buffers_get_velocity_texture(RID p_render_buffers) {
+ RenderBufferDataForwardClustered *rb = static_cast<RenderBufferDataForwardClustered *>(render_buffers_get_data(p_render_buffers));
+
+ return rb->msaa == RS::VIEWPORT_MSAA_DISABLED ? rb->velocity_buffer : rb->velocity_buffer_msaa;
}
RenderForwardClustered *RenderForwardClustered::singleton = nullptr;
@@ -3014,6 +3065,13 @@ void RenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstanc
void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
+
+ uint64_t frame = RSG::rasterizer->get_frame_number();
+ if (frame != ginstance->prev_transform_change_frame) {
+ ginstance->prev_transform = ginstance->transform;
+ ginstance->prev_transform_change_frame = frame;
+ ginstance->prev_transform_dirty = true;
+ }
ginstance->transform = p_transform;
ginstance->mirror = p_transform.basis.determinant() < 0;
ginstance->data->aabb = p_aabb;
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index bec10f7f0e..6ad42bf0ec 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -89,9 +89,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID specular;
RID normal_roughness_buffer;
RID voxelgi_buffer;
+ RID velocity_buffer;
RS::ViewportMSAA msaa;
RD::TextureSamples texture_samples;
+ bool use_taa;
RID color_msaa;
RID depth_msaa;
@@ -99,6 +101,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID normal_roughness_buffer_msaa;
RID roughness_buffer_msaa;
RID voxelgi_buffer_msaa;
+ RID velocity_buffer_msaa;
RID depth_fb;
RID depth_normal_roughness_fb;
@@ -112,8 +115,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID render_sdfgi_uniform_set;
void ensure_specular();
void ensure_voxelgi();
+ void ensure_velocity();
void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count);
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count);
RID get_color_pass_fb(uint32_t p_color_pass_flags);
~RenderBufferDataForwardClustered();
@@ -128,6 +132,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
virtual void _base_uniforms_changed() override;
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) override;
+ virtual RID _render_buffers_get_velocity_texture(RID p_render_buffers) override;
bool base_uniform_set_updated = false;
void _update_render_base_uniform_set();
@@ -148,7 +153,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
enum ColorPassFlags {
COLOR_PASS_FLAG_TRANSPARENT = 1 << 0,
COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 1,
- COLOR_PASS_FLAG_MULTIVIEW = 1 << 2
+ COLOR_PASS_FLAG_MULTIVIEW = 1 << 2,
+ COLOR_PASS_FLAG_MOTION_VECTORS = 1 << 3,
};
struct GeometryInstanceSurfaceDataCache;
@@ -300,6 +306,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float reflection_multiplier;
uint32_t pancake_shadows;
+
+ float taa_jitter[2];
+ uint32_t pad[2];
};
struct PushConstant {
@@ -310,6 +319,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
struct InstanceData {
float transform[16];
+ float prev_transform[16];
uint32_t flags;
uint32_t instance_uniforms_ofs; //base offset in global buffer for instance variables
uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap index)
@@ -317,7 +327,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float lightmap_uv_scale[4];
};
- UBO ubo;
+ UBO ubo_data[2];
+ UBO &ubo = ubo_data[0];
+ UBO &prev_ubo = ubo_data[1];
LocalVector<RID> uniform_buffers;
@@ -492,7 +504,10 @@ class RenderForwardClustered : public RendererSceneRenderRD {
//used during setup
uint32_t base_flags = 0;
+ uint64_t prev_transform_change_frame = 0xFFFFFFFF;
+ bool prev_transform_dirty = true;
Transform3D transform;
+ Transform3D prev_transform;
RID voxel_gi_instances[MAX_VOXEL_GI_INSTANCESS_PER_INSTANCE];
RID lightmap_instance;
GeometryInstanceLightmapSH *lightmap_sh = nullptr;
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index bd39dd9c70..cfb30ef2f3 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -235,10 +235,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
}
}
- // Color pass -> attachment 0: Color/Diffuse, attachment 1: Separate Specular
+ // Color pass -> attachment 0: Color/Diffuse, attachment 1: Separate Specular, attachment 2: Motion Vectors
RD::PipelineColorBlendState blend_state_color_blend;
- blend_state_color_blend.attachments = { blend_attachment, RD::PipelineColorBlendState::Attachment() };
- RD::PipelineColorBlendState blend_state_color_opaque = RD::PipelineColorBlendState::create_disabled(2);
+ blend_state_color_blend.attachments = { blend_attachment, RD::PipelineColorBlendState::Attachment(), RD::PipelineColorBlendState::Attachment() };
+ RD::PipelineColorBlendState blend_state_color_opaque = RD::PipelineColorBlendState::create_disabled(3);
RD::PipelineColorBlendState blend_state_depth_normal_roughness = RD::PipelineColorBlendState::create_disabled(1);
RD::PipelineColorBlendState blend_state_depth_normal_roughness_giprobe = RD::PipelineColorBlendState::create_disabled(2);
@@ -326,6 +326,10 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
}
}
+ if (l & PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS) {
+ shader_flags |= SHADER_COLOR_PASS_FLAG_MOTION_VECTORS;
+ }
+
if (l & PIPELINE_COLOR_PASS_FLAG_LIGHTMAP) {
shader_flags |= SHADER_COLOR_PASS_FLAG_LIGHTMAP;
}
@@ -532,6 +536,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
"\n#define MODE_SEPARATE_SPECULAR\n", // SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR
"\n#define USE_LIGHTMAP\n", // SHADER_COLOR_PASS_FLAG_LIGHTMAP
"\n#define USE_MULTIVIEW\n", // SHADER_COLOR_PASS_FLAG_MULTIVIEW
+ "\n#define MOTION_VECTORS\n", // SHADER_COLOR_PASS_FLAG_MOTION_VECTORS
};
for (int i = 0; i < SHADER_COLOR_PASS_FLAG_COUNT; i++) {
@@ -557,17 +562,29 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
- valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_TRANSPARENT | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
- valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR | PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_LIGHTMAP);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_LIGHTMAP | PIPELINE_COLOR_PASS_FLAG_MULTIVIEW | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_MULTIVIEW);
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_MULTIVIEW | PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
+
+ valid_color_pass_pipelines.insert(PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS);
material_storage->shader_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_shader_funcs);
material_storage->material_set_data_request_function(RendererRD::SHADER_TYPE_3D, _create_material_funcs);
@@ -604,7 +621,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
//builtins
- actions.renames["TIME"] = "scene_data.time";
+ actions.renames["TIME"] = "scene_data_block.data.time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
@@ -743,7 +760,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.base_texture_binding_index = 1;
actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET;
actions.base_uniform_string = "material.";
- actions.base_varying_index = 10;
+ actions.base_varying_index = 11;
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index c22b2f243d..79ccf10090 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -60,7 +60,8 @@ public:
SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 0,
SHADER_COLOR_PASS_FLAG_LIGHTMAP = 1 << 1,
SHADER_COLOR_PASS_FLAG_MULTIVIEW = 1 << 2,
- SHADER_COLOR_PASS_FLAG_COUNT = 1 << 3
+ SHADER_COLOR_PASS_FLAG_MOTION_VECTORS = 1 << 3,
+ SHADER_COLOR_PASS_FLAG_COUNT = 1 << 4
};
enum PipelineVersion {
@@ -80,7 +81,8 @@ public:
PIPELINE_COLOR_PASS_FLAG_SEPARATE_SPECULAR = 1 << 1,
PIPELINE_COLOR_PASS_FLAG_LIGHTMAP = 1 << 2,
PIPELINE_COLOR_PASS_FLAG_MULTIVIEW = 1 << 3,
- PIPELINE_COLOR_PASS_FLAG_COUNT = 1 << 4,
+ PIPELINE_COLOR_PASS_FLAG_MOTION_VECTORS = 1 << 4,
+ PIPELINE_COLOR_PASS_FLAG_COUNT = 1 << 5,
};
enum ShaderSpecializations {
@@ -239,7 +241,7 @@ public:
ShaderData *overdraw_material_shader_ptr = nullptr;
Vector<RD::PipelineSpecializationConstant> default_specialization_constants;
- RBSet<uint32_t> valid_color_pass_pipelines;
+ HashSet<uint32_t> valid_color_pass_pipelines;
SceneShaderForwardClustered();
~SceneShaderForwardClustered();
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 1cbf804ece..b2e0af06cd 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -87,7 +87,7 @@ void RenderForwardMobile::RenderBufferDataForwardMobile::clear() {
}
}
-void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
+void RenderForwardMobile::RenderBufferDataForwardMobile::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count) {
clear();
msaa = p_msaa;
@@ -485,9 +485,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RENDER_TIMESTAMP("Setup 3D Scene");
- Vector2 vp_he = p_render_data->cam_projection.get_viewport_half_extents();
- scene_state.ubo.viewport_size[0] = vp_he.x;
- scene_state.ubo.viewport_size[1] = vp_he.y;
scene_state.ubo.directional_light_count = 0;
scene_state.ubo.opaque_prepass_threshold = 0.0;
@@ -567,6 +564,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
ERR_FAIL(); //bug?
}
+ scene_state.ubo.viewport_size[0] = screen_size.x;
+ scene_state.ubo.viewport_size[1] = screen_size.y;
+
RD::get_singleton()->draw_command_begin_label("Render Setup");
_setup_lightmaps(*p_render_data->lightmaps, p_render_data->cam_transform);
@@ -1324,6 +1324,10 @@ RID RenderForwardMobile::_render_buffers_get_normal_texture(RID p_render_buffers
return RID();
}
+RID RenderForwardMobile::_render_buffers_get_velocity_texture(RID p_render_buffers) {
+ return RID();
+}
+
_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 1 };
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index 0a7e973120..fc6f32ecb0 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -136,7 +136,7 @@ protected:
uint32_t view_count;
void clear();
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count);
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count);
~RenderBufferDataForwardMobile();
};
@@ -224,6 +224,7 @@ protected:
virtual void _base_uniforms_changed() override;
void _update_render_base_uniform_set();
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) override;
+ virtual RID _render_buffers_get_velocity_texture(RID p_render_buffers) override;
void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append = false);
void _fill_element_info(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1);
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index a3cabb0693..f66ad529de 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -529,7 +529,7 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
//builtins
- actions.renames["TIME"] = "scene_data.time";
+ actions.renames["TIME"] = "scene_data_block.data.time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index e3bf2e3dda..ef959bc3c6 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -1935,6 +1935,21 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->ssr.normal_scaled = RID();
}
+ if (rb->taa.history.is_valid()) {
+ RD::get_singleton()->free(rb->taa.history);
+ rb->taa.history = RID();
+ }
+
+ if (rb->taa.temp.is_valid()) {
+ RD::get_singleton()->free(rb->taa.temp);
+ rb->taa.temp = RID();
+ }
+
+ if (rb->taa.prev_velocity.is_valid()) {
+ RD::get_singleton()->free(rb->taa.prev_velocity);
+ rb->taa.prev_velocity = RID();
+ }
+
if (rb->ambient_buffer.is_valid()) {
RD::get_singleton()->free(rb->ambient_buffer);
RD::get_singleton()->free(rb->reflection_buffer);
@@ -2323,6 +2338,41 @@ void RendererSceneRenderRD::_copy_framebuffer_to_ssil(RID p_render_buffers) {
}
}
+void RendererSceneRenderRD::_process_taa(RID p_render_buffers, RID p_velocity_buffer, float p_z_near, float p_z_far) {
+ RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
+ ERR_FAIL_COND(!rb);
+
+ bool just_allocated = false;
+ if (rb->taa.history.is_null()) {
+ RD::TextureFormat tf;
+ if (rb->view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ }
+ tf.format = _render_buffers_get_color_format();
+ tf.width = rb->internal_width;
+ tf.height = rb->internal_height;
+ tf.array_layers = rb->view_count; // create a layer for every view
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | (_render_buffers_can_be_storage() ? RD::TEXTURE_USAGE_STORAGE_BIT : 0);
+
+ rb->taa.history = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->taa.temp = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ tf.format = RD::DATA_FORMAT_R16G16_SFLOAT;
+ rb->taa.prev_velocity = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ just_allocated = true;
+ }
+
+ RD::get_singleton()->draw_command_begin_label("TAA");
+ if (!just_allocated) {
+ storage->get_effects()->taa_resolve(rb->internal_texture, rb->taa.temp, rb->depth_texture, p_velocity_buffer, rb->taa.prev_velocity, rb->taa.history, Size2(rb->internal_width, rb->internal_height), p_z_near, p_z_far);
+ copy_effects->copy_to_rect(rb->taa.temp, rb->internal_texture, Rect2(0, 0, rb->internal_width, rb->internal_height));
+ }
+
+ copy_effects->copy_to_rect(rb->internal_texture, rb->taa.history, Rect2(0, 0, rb->internal_width, rb->internal_height));
+ copy_effects->copy_to_rect(p_velocity_buffer, rb->taa.prev_velocity, Rect2(0, 0, rb->width, rb->height));
+ RD::get_singleton()->draw_command_end_label();
+}
+
void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderDataRD *p_render_data) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
ERR_FAIL_COND(!rb);
@@ -2388,6 +2438,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
bool can_use_storage = _render_buffers_can_be_storage();
if (can_use_effects && camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0) {
+ RENDER_TIMESTAMP("Depth of Field");
RD::get_singleton()->draw_command_begin_label("DOF");
if (rb->blur[0].texture.is_null()) {
_allocate_blur_textures(rb);
@@ -2440,6 +2491,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
}
if (can_use_effects && env && env->auto_exposure) {
+ RENDER_TIMESTAMP("Auto exposure");
RD::get_singleton()->draw_command_begin_label("Auto exposure");
if (rb->luminance.current.is_null()) {
_allocate_luminance_textures(rb);
@@ -2467,6 +2519,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
int max_glow_level = -1;
if (can_use_effects && env && env->glow_enabled) {
+ RENDER_TIMESTAMP("Glow");
RD::get_singleton()->draw_command_begin_label("Gaussian Glow");
/* see that blur textures are allocated */
@@ -2515,6 +2568,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
}
{
+ RENDER_TIMESTAMP("Tonemap");
RD::get_singleton()->draw_command_begin_label("Tonemap");
RendererRD::ToneMapper::TonemapSettings tonemap;
@@ -2755,6 +2809,11 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
copy_effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false);
}
}
+
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS && _render_buffers_get_velocity_texture(p_render_buffers).is_valid()) {
+ Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
+ copy_effects->copy_to_fb_rect(_render_buffers_get_velocity_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
+ }
}
void RendererSceneRenderRD::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, bool p_use_1d_color_correction, RID p_color_correction) {
@@ -2972,7 +3031,7 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() {
return true;
}
-void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) {
+void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
@@ -3000,6 +3059,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
rb->render_target = p_render_target;
rb->msaa = p_msaa;
rb->screen_space_aa = p_screen_space_aa;
+ rb->use_taa = p_use_taa;
rb->use_debanding = p_use_debanding;
rb->view_count = p_view_count;
@@ -3100,7 +3160,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
}
RID target_texture = texture_storage->render_target_get_rd_texture(rb->render_target);
- rb->data->configure(rb->internal_texture, rb->depth_texture, target_texture, p_internal_width, p_internal_height, p_msaa, p_view_count);
+ rb->data->configure(rb->internal_texture, rb->depth_texture, target_texture, p_internal_width, p_internal_height, p_msaa, p_use_taa, p_view_count);
if (is_clustered_enabled()) {
rb->cluster_builder->setup(Size2i(p_internal_width, p_internal_height), max_cluster_elements, rb->depth_texture, RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->internal_texture);
@@ -3397,7 +3457,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 (light_storage->light_has_shadow(base)) {
+ if (light_storage->light_has_shadow(base) && light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR) > 0.0) {
+ // Only enable PCSS-like soft shadows if blurring is enabled.
+ // Otherwise, performance would decrease with no visual difference.
r_directional_light_soft_shadows = true;
}
} else {
@@ -3676,7 +3738,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
RendererStorageRD::store_transform(proj, light_data.shadow_matrix);
- if (size > 0.0) {
+ if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
+ // Only enable PCSS-like soft shadows if blurring is enabled.
+ // Otherwise, performance would decrease with no visual difference.
light_data.soft_shadow_size = size;
} else {
light_data.soft_shadow_size = 0.0;
@@ -3693,7 +3757,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview;
RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix);
- if (size > 0.0) {
+ if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
+ // Only enable PCSS-like soft shadows if blurring is enabled.
+ // Otherwise, performance would decrease with no visual difference.
CameraMatrix cm = li->shadow_transform[0].camera;
float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle));
light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width;
@@ -4130,7 +4196,7 @@ Vector3i RendererSceneRenderRD::_point_get_position_in_froxel_volume(const Vecto
return Vector3i(fog_position);
}
-void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) {
+void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
@@ -4265,7 +4331,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.detail_spread = env->volumetric_fog_detail_spread;
params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount;
- Transform3D to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform;
+ Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
storage->store_transform(to_prev_cam_view, params.to_prev_view);
storage->store_transform(p_cam_transform, params.transform);
@@ -4361,7 +4427,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RS::FogVolumeShape volume_type = storage->fog_volume_get_shape(fog_volume);
Vector3 extents = storage->fog_volume_get_extents(fog_volume);
- if (volume_type == RS::FOG_VOLUME_SHAPE_BOX || volume_type == RS::FOG_VOLUME_SHAPE_ELLIPSOID) {
+ if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {
+ // Local fog volume.
Vector3i points[8];
points[0] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform);
points[1] = _point_get_position_in_froxel_volume(fog_volume_instance->transform.xform(Vector3(-extents.x, extents.y, extents.z)), fog_end, fog_near_size, fog_far_size, env->volumetric_fog_detail_spread, Vector3(rb->volumetric_fog->width, rb->volumetric_fog->height, rb->volumetric_fog->depth), p_cam_transform);
@@ -4742,7 +4809,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.max_voxel_gi_instances = env->volumetric_fog_gi_inject > 0.001 ? p_voxel_gi_count : 0;
params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
- Transform3D to_prev_cam_view = rb->volumetric_fog->prev_cam_transform.affine_inverse() * p_cam_transform;
+ Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
storage->store_transform(to_prev_cam_view, params.to_prev_view);
params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection;
@@ -4828,8 +4895,6 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RENDER_TIMESTAMP("< Volumetric Fog");
RD::get_singleton()->draw_command_end_label();
RD::get_singleton()->draw_command_end_label();
-
- rb->volumetric_fog->prev_cam_transform = p_cam_transform;
}
bool RendererSceneRenderRD::_needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi) {
@@ -5027,12 +5092,12 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
}
}
if (is_volumetric_supported()) {
- _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes);
+ _update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes);
}
}
}
-void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) {
+void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
// getting this here now so we can direct call a bunch of things more easily
@@ -5052,12 +5117,21 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
render_data.cam_projection = p_camera_data->main_projection;
render_data.view_projection[0] = p_camera_data->main_projection;
render_data.cam_orthogonal = p_camera_data->is_orthogonal;
+ render_data.taa_jitter = p_camera_data->taa_jitter;
render_data.view_count = p_camera_data->view_count;
for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
render_data.view_projection[v] = p_camera_data->view_projection[v];
}
+ render_data.prev_cam_transform = p_prev_camera_data->main_transform;
+ render_data.prev_cam_projection = p_prev_camera_data->main_projection;
+ render_data.prev_taa_jitter = p_prev_camera_data->taa_jitter;
+
+ for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
+ render_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v];
+ }
+
render_data.z_near = p_camera_data->main_projection.get_z_near();
render_data.z_far = p_camera_data->main_projection.get_z_far();
@@ -5170,7 +5244,6 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
if (p_render_buffers.is_valid()) {
/*
_debug_draw_cluster(p_render_buffers);
- RENDER_TIMESTAMP("Tonemap");
_render_buffers_post_process_and_tonemap(&render_data);
*/
@@ -5464,8 +5537,8 @@ bool RendererSceneRenderRD::free(RID p_rid) {
LightInstance *light_instance = light_instance_owner.get_or_null(p_rid);
//remove from shadow atlases..
- for (RBSet<RID>::Element *E = light_instance->shadow_atlases.front(); E; E = E->next()) {
- ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E->get());
+ for (const RID &E : light_instance->shadow_atlases) {
+ ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E);
ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_rid));
uint32_t key = shadow_atlas->shadow_owners[p_rid];
uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 4daee17525..1b1df6469e 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -53,12 +53,18 @@ struct RenderDataRD {
Transform3D cam_transform;
CameraMatrix cam_projection;
+ Vector2 taa_jitter;
bool cam_orthogonal = false;
// For stereo rendering
uint32_t view_count = 1;
CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
+ Transform3D prev_cam_transform;
+ CameraMatrix prev_cam_projection;
+ Vector2 prev_taa_jitter;
+ CameraMatrix prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
+
float z_near = 0.0;
float z_far = 0.0;
@@ -103,7 +109,7 @@ protected:
double time_step = 0.0;
struct RenderBufferData {
- virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) = 0;
+ virtual void configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, bool p_use_taa, uint32_t p_view_count) = 0;
virtual ~RenderBufferData() {}
};
virtual RenderBufferData *_create_render_buffer_data() = 0;
@@ -131,13 +137,14 @@ protected:
virtual void _base_uniforms_changed() = 0;
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0;
+ virtual RID _render_buffers_get_velocity_texture(RID p_render_buffers) = 0;
void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection);
void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive);
void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera);
void _process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform);
void _copy_framebuffer_to_ssil(RID p_render_buffers);
- void _ensure_ss_effects(RID p_render_buffers, bool p_using_ssil);
+ void _process_taa(RID p_render_buffers, RID p_velocity_buffer, float p_z_near, float p_z_far);
bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
@@ -387,7 +394,7 @@ private:
Rect2 directional_rect;
- RBSet<RID> shadow_atlases; //shadow atlases where this light is registered
+ HashSet<RID> shadow_atlases; //shadow atlases where this light is registered
ForwardID forward_id = -1;
@@ -472,6 +479,7 @@ private:
float fsr_sharpness = 0.2f;
RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
RS::ViewportScreenSpaceAA screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;
+ bool use_taa = false;
bool use_debanding = false;
uint32_t view_count = 1;
@@ -592,6 +600,12 @@ private:
RID blur_radius[2];
} ssr;
+ struct TAA {
+ RID history;
+ RID temp;
+ RID prev_velocity; // Last frame velocity buffer
+ } taa;
+
RID ambient_buffer;
RID reflection_buffer;
};
@@ -793,8 +807,6 @@ private:
RID sky_uniform_set;
int last_shadow_filter = -1;
-
- Transform3D prev_cam_transform;
};
struct VolumetricFogShader {
@@ -914,7 +926,7 @@ private:
Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform);
void _volumetric_fog_erase(RenderBuffers *rb);
- void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
+ void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
struct FogShaderData : public RendererRD::ShaderData {
bool valid = false;
@@ -1385,7 +1397,7 @@ public:
virtual RD::DataFormat _render_buffers_get_color_format();
virtual bool _render_buffers_can_be_storage();
virtual RID render_buffers_create() override;
- virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) override;
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override;
virtual void gi_set_use_half_resolution(bool p_enable) override;
RID render_buffers_get_depth_texture(RID p_render_buffers);
@@ -1419,7 +1431,7 @@ public:
virtual void update_uniform_sets(){};
- virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override;
+ virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override;
virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 14a5f02eee..3a237dbd8c 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -846,6 +846,7 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
actions.renames["POSITION"] = "params.position_multiplier.xyz";
actions.renames["SKY_COORDS"] = "panorama_coords";
actions.renames["SCREEN_UV"] = "uv";
+ actions.renames["FRAGCOORD"] = "gl_FragCoord";
actions.renames["TIME"] = "params.time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
@@ -1530,7 +1531,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
projections = &camera;
}
- sky_transform = p_transform.basis * sky_transform;
+ sky_transform = sky_transform * p_transform.basis;
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index cf642c38c9..d5166c6905 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -97,6 +97,8 @@ AABB RendererStorageRD::fog_volume_get_aabb(RID p_fog_volume) const {
switch (fog_volume->shape) {
case RS::FOG_VOLUME_SHAPE_ELLIPSOID:
+ case RS::FOG_VOLUME_SHAPE_CONE:
+ case RS::FOG_VOLUME_SHAPE_CYLINDER:
case RS::FOG_VOLUME_SHAPE_BOX: {
AABB aabb;
aabb.position = -fog_volume->extents;
@@ -590,6 +592,10 @@ void RendererStorageRD::update_dirty_resources() {
}
bool RendererStorageRD::has_os_feature(const String &p_feature) const {
+ if (!RD::get_singleton()) {
+ return false;
+ }
+
if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
return true;
}
diff --git a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl
index 5a238452c0..a8ccdea60b 100644
--- a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl
@@ -426,12 +426,13 @@ vec3 screen_space_dither(vec2 frag_coord) {
void main() {
#ifdef SUBPASS
// SUBPASS and MULTIVIEW can be combined but in that case we're already reading from the correct layer
- vec3 color = subpassLoad(input_color).rgb * params.luminance_multiplier;
+ vec4 color = subpassLoad(input_color);
#elif defined(MULTIVIEW)
- vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb * params.luminance_multiplier;
+ vec4 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f);
#else
- vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb * params.luminance_multiplier;
+ vec4 color = textureLod(source_color, uv_interp, 0.0f);
#endif
+ color.rgb *= params.luminance_multiplier;
// Exposure
@@ -443,7 +444,7 @@ void main() {
}
#endif
- color *= exposure;
+ color.rgb *= exposure;
// Early Tonemap & SRGB Conversion
#ifndef SUBPASS
@@ -456,19 +457,19 @@ void main() {
}
if (params.use_fxaa) {
- color = do_fxaa(color, exposure, uv_interp);
+ color.rgb = do_fxaa(color.rgb, exposure, uv_interp);
}
#endif
if (params.use_debanding) {
// For best results, debanding should be done before tonemapping.
// Otherwise, we're adding noise to an already-quantized image.
- color += screen_space_dither(gl_FragCoord.xy);
+ color.rgb += screen_space_dither(gl_FragCoord.xy);
}
- color = apply_tonemapping(color, params.white);
+ color.rgb = apply_tonemapping(color.rgb, params.white);
- color = linear_to_srgb(color); // regular linear -> SRGB conversion
+ color.rgb = linear_to_srgb(color.rgb); // regular linear -> SRGB conversion
#ifndef SUBPASS
// Glow
@@ -482,19 +483,19 @@ void main() {
glow = apply_tonemapping(glow, params.white);
glow = linear_to_srgb(glow);
- color = apply_glow(color, glow);
+ color.rgb = apply_glow(color.rgb, glow);
}
#endif
// Additional effects
if (params.use_bcs) {
- color = apply_bcs(color, params.bcs);
+ color.rgb = apply_bcs(color.rgb, params.bcs);
}
if (params.use_color_correction) {
- color = apply_color_correction(color);
+ color.rgb = apply_color_correction(color.rgb);
}
- frag_color = vec4(color, 1.0f);
+ frag_color = color;
}
diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index 1b1051ecfa..acb62b812e 100644
--- a/servers/rendering/renderer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -228,6 +228,14 @@ bool emit_subparticle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom
return true;
}
+vec3 safe_normalize(vec3 direction) {
+ const float EPSILON = 0.001;
+ if (length(direction) < EPSILON) {
+ return vec3(0.0);
+ }
+ return normalize(direction);
+}
+
#GLOBALS
void main() {
@@ -431,7 +439,7 @@ void main() {
switch (FRAME.attractors[i].type) {
case ATTRACTOR_TYPE_SPHERE: {
- dir = normalize(rel_vec);
+ dir = safe_normalize(rel_vec);
float d = length(local_pos) / FRAME.attractors[i].extents.x;
if (d > 1.0) {
continue;
@@ -439,7 +447,7 @@ void main() {
amount = max(0.0, 1.0 - d);
} break;
case ATTRACTOR_TYPE_BOX: {
- dir = normalize(rel_vec);
+ dir = safe_normalize(rel_vec);
vec3 abs_pos = abs(local_pos / FRAME.attractors[i].extents);
float d = max(abs_pos.x, max(abs_pos.y, abs_pos.z));
@@ -455,13 +463,13 @@ void main() {
continue;
}
vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz;
- dir = mat3(FRAME.attractors[i].transform) * normalize(s); //revert direction
+ dir = mat3(FRAME.attractors[i].transform) * safe_normalize(s); //revert direction
amount = length(s);
} break;
}
amount = pow(amount, FRAME.attractors[i].attenuation);
- dir = normalize(mix(dir, FRAME.attractors[i].transform[2].xyz, FRAME.attractors[i].directionality));
+ dir = safe_normalize(mix(dir, FRAME.attractors[i].transform[2].xyz, FRAME.attractors[i].directionality));
attractor_force -= amount * dir * FRAME.attractors[i].strength;
}
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index 4f49c186a6..92c4fc3d67 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -83,6 +83,11 @@ layout(location = 5) out vec3 tangent_interp;
layout(location = 6) out vec3 binormal_interp;
#endif
+#ifdef MOTION_VECTORS
+layout(location = 7) out vec4 screen_position;
+layout(location = 8) out vec4 prev_screen_position;
+#endif
+
#ifdef MATERIAL_UNIFORMS_USED
layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
@@ -93,11 +98,11 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms
#ifdef MODE_DUAL_PARABOLOID
-layout(location = 8) out float dp_clip;
+layout(location = 9) out float dp_clip;
#endif
-layout(location = 9) out flat uint instance_index_interp;
+layout(location = 10) out flat uint instance_index_interp;
#ifdef USE_MULTIVIEW
#ifdef has_VK_KHR_multiview
@@ -115,23 +120,12 @@ invariant gl_Position;
#GLOBALS
-void main() {
+void vertex_shader(in uint instance_index, in bool is_multimesh, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) {
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
color_interp = color_attrib;
#endif
- uint instance_index = draw_call.instance_index;
-
- bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH);
- if (!is_multimesh) {
- instance_index += gl_InstanceIndex;
- }
-
- instance_index_interp = instance_index;
-
- mat4 model_matrix = instances.data[instance_index].transform;
-
mat3 model_normal_matrix;
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
model_normal_matrix = transpose(inverse(mat3(model_matrix)));
@@ -321,6 +315,11 @@ void main() {
#endif
vertex_interp = vertex;
+
+#ifdef MOTION_VECTORS
+ screen_pos = projection_matrix * vec4(vertex_interp, 1.0);
+#endif
+
#ifdef NORMAL_USED
normal_interp = normal;
#endif
@@ -375,6 +374,26 @@ void main() {
#endif
}
+void main() {
+ uint instance_index = draw_call.instance_index;
+
+ bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH);
+ if (!is_multimesh) {
+ instance_index += gl_InstanceIndex;
+ }
+
+ instance_index_interp = instance_index;
+
+ mat4 model_matrix = instances.data[instance_index].transform;
+#if defined(MOTION_VECTORS)
+ vertex_shader(instance_index, is_multimesh, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position);
+ vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position);
+#else
+ vec4 screen_position;
+ vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position);
+#endif
+}
+
#[fragment]
#version 450
@@ -431,13 +450,18 @@ layout(location = 5) in vec3 tangent_interp;
layout(location = 6) in vec3 binormal_interp;
#endif
+#ifdef MOTION_VECTORS
+layout(location = 7) in vec4 screen_position;
+layout(location = 8) in vec4 prev_screen_position;
+#endif
+
#ifdef MODE_DUAL_PARABOLOID
-layout(location = 8) in float dp_clip;
+layout(location = 9) in float dp_clip;
#endif
-layout(location = 9) in flat uint instance_index_interp;
+layout(location = 10) in flat uint instance_index_interp;
#ifdef USE_MULTIVIEW
#ifdef has_VK_KHR_multiview
@@ -510,6 +534,10 @@ layout(location = 0) out vec4 frag_color;
#endif // RENDER DEPTH
+#ifdef MOTION_VECTORS
+layout(location = 2) out vec2 motion_vector;
+#endif
+
#include "scene_forward_aa_inc.glsl"
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
@@ -528,24 +556,24 @@ layout(location = 0) out vec4 frag_color;
#ifndef MODE_RENDER_DEPTH
vec4 volumetric_fog_process(vec2 screen_uv, float z) {
- vec3 fog_pos = vec3(screen_uv, z * scene_data.volumetric_fog_inv_length);
+ vec3 fog_pos = vec3(screen_uv, z * scene_data_block.data.volumetric_fog_inv_length);
if (fog_pos.z < 0.0) {
return vec4(0.0);
} else if (fog_pos.z < 1.0) {
- fog_pos.z = pow(fog_pos.z, scene_data.volumetric_fog_detail_spread);
+ fog_pos.z = pow(fog_pos.z, scene_data_block.data.volumetric_fog_detail_spread);
}
return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos);
}
vec4 fog_process(vec3 vertex) {
- vec3 fog_color = scene_data.fog_light_color;
+ vec3 fog_color = scene_data_block.data.fog_light_color;
- if (scene_data.fog_aerial_perspective > 0.0) {
+ if (scene_data_block.data.fog_aerial_perspective > 0.0) {
vec3 sky_fog_color = vec3(0.0);
- vec3 cube_view = scene_data.radiance_inverse_xform * vertex;
+ vec3 cube_view = scene_data_block.data.radiance_inverse_xform * vertex;
// mip_level always reads from the second mipmap and higher so the fog is always slightly blurred
- float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near));
+ float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data_block.data.z_near) / (scene_data_block.data.z_far - scene_data_block.data.z_near));
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
blend = modf(mip_level * MAX_ROUGHNESS_LOD, lod);
@@ -554,29 +582,29 @@ vec4 fog_process(vec3 vertex) {
#else
sky_fog_color = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_view, mip_level * MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
- fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective);
+ fog_color = mix(fog_color, sky_fog_color, scene_data_block.data.fog_aerial_perspective);
}
- if (scene_data.fog_sun_scatter > 0.001) {
+ if (scene_data_block.data.fog_sun_scatter > 0.001) {
vec4 sun_scatter = vec4(0.0);
float sun_total = 0.0;
vec3 view = normalize(vertex);
- for (uint i = 0; i < scene_data.directional_light_count; i++) {
+ for (uint i = 0; i < scene_data_block.data.directional_light_count; i++) {
vec3 light_color = directional_lights.data[i].color * directional_lights.data[i].energy;
float light_amount = pow(max(dot(view, directional_lights.data[i].direction), 0.0), 8.0);
- fog_color += light_color * light_amount * scene_data.fog_sun_scatter;
+ fog_color += light_color * light_amount * scene_data_block.data.fog_sun_scatter;
}
}
- float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density));
+ float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data_block.data.fog_density));
- if (abs(scene_data.fog_height_density) >= 0.0001) {
- float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y;
+ if (abs(scene_data_block.data.fog_height_density) >= 0.0001) {
+ float y = (scene_data_block.data.inv_view_matrix * vec4(vertex, 1.0)).y;
- float y_dist = y - scene_data.fog_height;
+ float y_dist = y - scene_data_block.data.fog_height;
- float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density));
+ float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data_block.data.fog_height_density));
fog_amount = max(vfog_amount, fog_amount);
}
@@ -601,13 +629,7 @@ uint cluster_get_range_clip_mask(uint i, uint z_min, uint z_max) {
#endif //!MODE_RENDER DEPTH
-void main() {
-#ifdef MODE_DUAL_PARABOLOID
-
- if (dp_clip > 0.0)
- discard;
-#endif
-
+void fragment_shader(in SceneData scene_data) {
uint instance_index = instance_index_interp;
//lay out everything, whatever is unused is optimized away anyway
@@ -2015,4 +2037,23 @@ void main() {
#endif //MODE_SEPARATE_SPECULAR
#endif //MODE_RENDER_DEPTH
+#ifdef MOTION_VECTORS
+ vec2 position_clip = (screen_position.xy / screen_position.w) - scene_data.taa_jitter;
+ vec2 prev_position_clip = (prev_screen_position.xy / prev_screen_position.w) - scene_data_block.prev_data.taa_jitter;
+
+ vec2 position_uv = position_clip * vec2(0.5, 0.5);
+ vec2 prev_position_uv = prev_position_clip * vec2(0.5, 0.5);
+
+ motion_vector = position_uv - prev_position_uv;
+#endif
+}
+
+void main() {
+#ifdef MODE_DUAL_PARABOLOID
+
+ if (dp_clip > 0.0)
+ discard;
+#endif
+
+ fragment_shader(scene_data_block.data);
}
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 f2672f10e7..b700e21543 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -171,7 +171,7 @@ sdfgi;
/* Set 1: Render Pass (changes per render pass) */
-layout(set = 1, binding = 0, std140) uniform SceneData {
+struct SceneData {
mat4 projection_matrix;
mat4 inv_projection_matrix;
mat4 inv_view_matrix;
@@ -249,11 +249,19 @@ layout(set = 1, binding = 0, std140) uniform SceneData {
float reflection_multiplier; // one normally, zero when rendering reflections
bool pancake_shadows;
+ vec2 taa_jitter;
+ uvec2 pad;
+};
+
+layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
+ SceneData data;
+ SceneData prev_data;
}
-scene_data;
+scene_data_block;
struct InstanceData {
mat4 transform;
+ mat4 prev_transform;
uint flags;
uint instance_uniforms_ofs; //base offset in global buffer for instance variables
uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
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 bd1c2b5758..5a308bbd02 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -262,7 +262,7 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve
float avg = 0.0;
for (uint i = 0; i < sc_directional_soft_shadow_samples; i++) {
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data.directional_soft_shadow_kernel[i].xy), depth, 1.0));
+ avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data_block.data.directional_soft_shadow_kernel[i].xy), depth, 1.0));
}
return avg * (1.0 / float(sc_directional_soft_shadow_samples));
@@ -288,7 +288,7 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec3 coord) {
float avg = 0.0;
for (uint i = 0; i < sc_soft_shadow_samples; i++) {
- avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data.soft_shadow_kernel[i].xy), depth, 1.0));
+ avg += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(pos + shadow_pixel_size * (disk_rotation * scene_data_block.data.soft_shadow_kernel[i].xy), depth, 1.0));
}
return avg * (1.0 / float(sc_soft_shadow_samples));
@@ -311,10 +311,10 @@ float sample_omni_pcf_shadow(texture2D shadow, float blur_scale, vec2 coord, vec
}
float avg = 0.0;
- vec2 offset_scale = blur_scale * 2.0 * scene_data.shadow_atlas_pixel_size / uv_rect.zw;
+ vec2 offset_scale = blur_scale * 2.0 * scene_data_block.data.shadow_atlas_pixel_size / uv_rect.zw;
for (uint i = 0; i < sc_soft_shadow_samples; i++) {
- vec2 offset = offset_scale * (disk_rotation * scene_data.soft_shadow_kernel[i].xy);
+ vec2 offset = offset_scale * (disk_rotation * scene_data_block.data.soft_shadow_kernel[i].xy);
vec2 sample_coord = coord + offset;
float sample_coord_length_sqaured = dot(sample_coord, sample_coord);
@@ -351,7 +351,7 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex
}
for (uint i = 0; i < sc_directional_penumbra_shadow_samples; i++) {
- vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale;
+ vec2 suv = pssm_coord.xy + (disk_rotation * scene_data_block.data.directional_penumbra_shadow_kernel[i].xy) * tex_scale;
float d = textureLod(sampler2D(shadow, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r;
if (d < pssm_coord.z) {
blocker_average += d;
@@ -367,7 +367,7 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex
float s = 0.0;
for (uint i = 0; i < sc_directional_penumbra_shadow_samples; i++) {
- vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale;
+ vec2 suv = pssm_coord.xy + (disk_rotation * scene_data_block.data.directional_penumbra_shadow_kernel[i].xy) * tex_scale;
s += textureProj(sampler2DShadow(shadow, shadow_sampler), vec4(suv, pssm_coord.z, 1.0));
}
@@ -394,7 +394,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {
#ifndef SHADOWS_DISABLED
if (omni_lights.data[idx].shadow_enabled) {
// there is a shadowmap
- vec2 texel_size = scene_data.shadow_atlas_pixel_size;
+ vec2 texel_size = scene_data_block.data.shadow_atlas_pixel_size;
vec4 base_uv_rect = omni_lights.data[idx].atlas_rect;
base_uv_rect.xy += texel_size;
base_uv_rect.zw -= texel_size * 2.0;
@@ -438,7 +438,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {
bitangent *= omni_lights.data[idx].soft_shadow_size * omni_lights.data[idx].soft_shadow_scale;
for (uint i = 0; i < sc_penumbra_shadow_samples; i++) {
- vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy;
+ vec2 disk = disk_rotation * scene_data_block.data.penumbra_shadow_kernel[i].xy;
vec3 pos = local_vert + tangent * disk.x + bitangent * disk.y;
@@ -474,7 +474,7 @@ float light_process_omni_shadow(uint idx, vec3 vertex, vec3 normal) {
shadow = 0.0;
for (uint i = 0; i < sc_penumbra_shadow_samples; i++) {
- vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy;
+ vec2 disk = disk_rotation * scene_data_block.data.penumbra_shadow_kernel[i].xy;
vec3 pos = local_vert + tangent * disk.x + bitangent * disk.y;
pos = normalize(pos);
@@ -579,7 +579,7 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
splane.xy = splane.xy * 0.5 + 0.5;
splane.z = shadow_len * omni_lights.data[idx].inv_radius;
splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
- // splane.xy = clamp(splane.xy,clamp_rect.xy + scene_data.shadow_atlas_pixel_size,clamp_rect.xy + clamp_rect.zw - scene_data.shadow_atlas_pixel_size );
+ // splane.xy = clamp(splane.xy,clamp_rect.xy + scene_data_block.data.shadow_atlas_pixel_size,clamp_rect.xy + clamp_rect.zw - scene_data_block.data.shadow_atlas_pixel_size );
splane.w = 1.0; //needed? i think it should be 1 already
float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
@@ -709,7 +709,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
float uv_size = spot_lights.data[idx].soft_shadow_size * z_norm * spot_lights.data[idx].soft_shadow_scale;
vec2 clamp_max = spot_lights.data[idx].atlas_rect.xy + spot_lights.data[idx].atlas_rect.zw;
for (uint i = 0; i < sc_penumbra_shadow_samples; i++) {
- vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size;
+ vec2 suv = shadow_uv + (disk_rotation * scene_data_block.data.penumbra_shadow_kernel[i].xy) * uv_size;
suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max);
float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r;
if (d < splane.z) {
@@ -726,7 +726,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
shadow = 0.0;
for (uint i = 0; i < sc_penumbra_shadow_samples; i++) {
- vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size;
+ vec2 suv = shadow_uv + (disk_rotation * scene_data_block.data.penumbra_shadow_kernel[i].xy) * uv_size;
suv = clamp(suv, spot_lights.data[idx].atlas_rect.xy, clamp_max);
shadow += textureProj(sampler2DShadow(shadow_atlas, shadow_sampler), vec4(suv, splane.z, 1.0));
}
@@ -740,7 +740,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
} else {
//hard shadow
vec3 shadow_uv = vec3(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z);
- shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv);
+ shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data_block.data.shadow_atlas_pixel_size, shadow_uv);
}
return shadow;
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
index fd0fefc5fd..e15ebbfc91 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
@@ -115,6 +115,8 @@ invariant gl_Position;
#GLOBALS
void main() {
+ SceneData scene_data = scene_data_block.data;
+
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
color_interp = color_attrib;
@@ -527,13 +529,13 @@ layout(location = 0) out mediump vec4 frag_color;
*/
vec4 fog_process(vec3 vertex) {
- vec3 fog_color = scene_data.fog_light_color;
+ vec3 fog_color = scene_data_block.data.fog_light_color;
- if (scene_data.fog_aerial_perspective > 0.0) {
+ if (scene_data_block.data.fog_aerial_perspective > 0.0) {
vec3 sky_fog_color = vec3(0.0);
- vec3 cube_view = scene_data.radiance_inverse_xform * vertex;
+ vec3 cube_view = scene_data_block.data.radiance_inverse_xform * vertex;
// mip_level always reads from the second mipmap and higher so the fog is always slightly blurred
- float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data.z_near) / (scene_data.z_far - scene_data.z_near));
+ float mip_level = mix(1.0 / MAX_ROUGHNESS_LOD, 1.0, 1.0 - (abs(vertex.z) - scene_data_block.data.z_near) / (scene_data_block.data.z_far - scene_data_block.data.z_near));
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
float lod, blend;
blend = modf(mip_level * MAX_ROUGHNESS_LOD, lod);
@@ -542,29 +544,29 @@ vec4 fog_process(vec3 vertex) {
#else
sky_fog_color = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_view, mip_level * MAX_ROUGHNESS_LOD).rgb;
#endif //USE_RADIANCE_CUBEMAP_ARRAY
- fog_color = mix(fog_color, sky_fog_color, scene_data.fog_aerial_perspective);
+ fog_color = mix(fog_color, sky_fog_color, scene_data_block.data.fog_aerial_perspective);
}
- if (scene_data.fog_sun_scatter > 0.001) {
+ if (scene_data_block.data.fog_sun_scatter > 0.001) {
vec4 sun_scatter = vec4(0.0);
float sun_total = 0.0;
vec3 view = normalize(vertex);
- for (uint i = 0; i < scene_data.directional_light_count; i++) {
+ for (uint i = 0; i < scene_data_block.data.directional_light_count; i++) {
vec3 light_color = directional_lights.data[i].color * directional_lights.data[i].energy;
float light_amount = pow(max(dot(view, directional_lights.data[i].direction), 0.0), 8.0);
- fog_color += light_color * light_amount * scene_data.fog_sun_scatter;
+ fog_color += light_color * light_amount * scene_data_block.data.fog_sun_scatter;
}
}
- float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density));
+ float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data_block.data.fog_density));
- if (abs(scene_data.fog_height_density) >= 0.0001) {
- float y = (scene_data.inv_view_matrix * vec4(vertex, 1.0)).y;
+ if (abs(scene_data_block.data.fog_height_density) >= 0.0001) {
+ float y = (scene_data_block.data.inv_view_matrix * vec4(vertex, 1.0)).y;
- float y_dist = y - scene_data.fog_height;
+ float y_dist = y - scene_data_block.data.fog_height;
- float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density));
+ float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data_block.data.fog_height_density));
fog_amount = max(vfog_amount, fog_amount);
}
@@ -580,6 +582,7 @@ void main() {
if (dp_clip > 0.0)
discard;
#endif
+ SceneData scene_data = scene_data_block.data;
//lay out everything, whatever is unused is optimized away anyway
vec3 vertex = vertex_interp;
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 91ef19ab67..dd14a15837 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl
@@ -125,7 +125,7 @@ global_variables;
/* Set 1: Render Pass (changes per render pass) */
-layout(set = 1, binding = 0, std140) uniform SceneData {
+struct SceneData {
highp mat4 projection_matrix;
highp mat4 inv_projection_matrix;
highp mat4 inv_view_matrix;
@@ -189,8 +189,12 @@ layout(set = 1, binding = 0, std140) uniform SceneData {
uint pad1;
uint pad2;
uint pad3;
+};
+
+layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
+ SceneData data;
}
-scene_data;
+scene_data_block;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl
index 4ef6a26443..a893a66c94 100644
--- a/servers/rendering/renderer_rd/shaders/skeleton.glsl
+++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl
@@ -160,7 +160,7 @@ void main() {
}
if (params.has_tangent) {
- blend_tangent += decode_abgr_2_10_10_10(src_blend_shapes.data[base_offset]).rgb;
+ blend_tangent += decode_abgr_2_10_10_10(src_blend_shapes.data[base_offset]).rgb * w;
}
blend_total += w;
@@ -174,8 +174,8 @@ void main() {
}
vertex += blend_vertex;
- normal += normalize(normal + blend_normal);
- tangent.rgb += normalize(tangent.rgb + blend_tangent);
+ normal = normalize(normal + blend_normal);
+ tangent.rgb = normalize(tangent.rgb + blend_tangent);
}
if (params.has_skeleton) {
diff --git a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl b/servers/rendering/renderer_rd/shaders/ssil_blur.glsl
index ee21d46a74..47c56571f6 100644
--- a/servers/rendering/renderer_rd/shaders/ssil_blur.glsl
+++ b/servers/rendering/renderer_rd/shaders/ssil_blur.glsl
@@ -1,3 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2016, Intel Corporation
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+// the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2016-09-07: filip.strugar@intel.com: first commit
+// 2020-12-05: clayjohn: convert to Vulkan and Godot
+// 2021-05-27: clayjohn: convert SSAO to SSIL
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
#[compute]
#version 450
diff --git a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl b/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl
index 8818f8cada..6b6b02739d 100644
--- a/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl
+++ b/servers/rendering/renderer_rd/shaders/ssil_importance_map.glsl
@@ -15,6 +15,7 @@
// File changes (yyyy-mm-dd)
// 2016-09-07: filip.strugar@intel.com: first commit
// 2020-12-05: clayjohn: convert to Vulkan and Godot
+// 2021-05-27: clayjohn: convert SSAO to SSIL
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#[compute]
diff --git a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl b/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl
index fa4309353d..9e86ac0cf0 100644
--- a/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl
+++ b/servers/rendering/renderer_rd/shaders/ssil_interleave.glsl
@@ -1,3 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright (c) 2016, Intel Corporation
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+// documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+// the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
+// THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2016-09-07: filip.strugar@intel.com: first commit
+// 2020-12-05: clayjohn: convert to Vulkan and Godot
+// 2021-05-27: clayjohn: convert SSAO to SSIL
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
#[compute]
#version 450
diff --git a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
new file mode 100644
index 0000000000..a1a77b95aa
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
@@ -0,0 +1,393 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright(c) 2016-2022 Panos Karabelas
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
+// copies of the Software, and to permit persons to whom the Software is furnished
+// to do so, subject to the following conditions :
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR
+// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+///////////////////////////////////////////////////////////////////////////////////
+// File changes (yyyy-mm-dd)
+// 2022-05-06: Panos Karabelas: first commit
+// 2020-12-05: Joan Fons: convert to Vulkan and Godot
+///////////////////////////////////////////////////////////////////////////////////
+
+#[compute]
+
+#version 450
+
+#VERSION_DEFINES
+
+// Based on Spartan Engine's TAA implementation https://github.com/PanosK92/SpartanEngine/blob/master/Data/shaders/temporal_antialiasing.hlsl
+
+#define USE_SUBGROUPS
+
+#define GROUP_SIZE 8
+#define FLT_MIN 0.00000001
+#define FLT_MAX 32767.0
+#define RPC_9 0.11111111111
+#define RPC_16 0.0625
+
+#ifdef USE_SUBGROUPS
+layout(local_size_x = GROUP_SIZE, local_size_y = GROUP_SIZE, local_size_z = 1) in;
+#endif
+
+layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D color_buffer;
+layout(set = 0, binding = 1) uniform sampler2D depth_buffer;
+layout(rg16f, set = 0, binding = 2) uniform restrict readonly image2D velocity_buffer;
+layout(rg16f, set = 0, binding = 3) uniform restrict readonly image2D last_velocity_buffer;
+layout(set = 0, binding = 4) uniform sampler2D history_buffer;
+layout(rgba16f, set = 0, binding = 5) uniform restrict writeonly image2D output_buffer;
+
+layout(push_constant, std430) uniform Params {
+ vec2 resolution;
+ float disocclusion_threshold; // 0.1 / max(params.resolution.x, params.resolution.y
+ float disocclusion_scale;
+}
+params;
+
+const ivec2 kOffsets3x3[9] = {
+ ivec2(-1, -1),
+ ivec2(0, -1),
+ ivec2(1, -1),
+ ivec2(-1, 0),
+ ivec2(0, 0),
+ ivec2(1, 0),
+ ivec2(-1, 1),
+ ivec2(0, 1),
+ ivec2(1, 1),
+};
+
+/*------------------------------------------------------------------------------
+ THREAD GROUP SHARED MEMORY (LDS)
+------------------------------------------------------------------------------*/
+
+const int kBorderSize = 1;
+const int kGroupSize = GROUP_SIZE;
+const int kTileDimension = kGroupSize + kBorderSize * 2;
+const int kTileDimension2 = kTileDimension * kTileDimension;
+
+vec3 reinhard(vec3 hdr) {
+ return hdr / (hdr + 1.0);
+}
+vec3 reinhard_inverse(vec3 sdr) {
+ return sdr / (1.0 - sdr);
+}
+
+float get_depth(ivec2 thread_id) {
+ return texelFetch(depth_buffer, thread_id, 0).r;
+}
+
+#ifdef USE_SUBGROUPS
+shared vec3 tile_color[kTileDimension][kTileDimension];
+shared float tile_depth[kTileDimension][kTileDimension];
+
+vec3 load_color(uvec2 group_thread_id) {
+ group_thread_id += kBorderSize;
+ return tile_color[group_thread_id.x][group_thread_id.y];
+}
+
+void store_color(uvec2 group_thread_id, vec3 color) {
+ tile_color[group_thread_id.x][group_thread_id.y] = color;
+}
+
+float load_depth(uvec2 group_thread_id) {
+ group_thread_id += kBorderSize;
+ return tile_depth[group_thread_id.x][group_thread_id.y];
+}
+
+void store_depth(uvec2 group_thread_id, float depth) {
+ tile_depth[group_thread_id.x][group_thread_id.y] = depth;
+}
+
+void store_color_depth(uvec2 group_thread_id, ivec2 thread_id) {
+ // out of bounds clamp
+ thread_id = clamp(thread_id, ivec2(0, 0), ivec2(params.resolution) - ivec2(1, 1));
+
+ store_color(group_thread_id, imageLoad(color_buffer, thread_id).rgb);
+ store_depth(group_thread_id, get_depth(thread_id));
+}
+
+void populate_group_shared_memory(uvec2 group_id, uint group_index) {
+ // Populate group shared memory
+ ivec2 group_top_left = ivec2(group_id) * kGroupSize - kBorderSize;
+ if (group_index < (kTileDimension2 >> 2)) {
+ ivec2 group_thread_id_1 = ivec2(group_index % kTileDimension, group_index / kTileDimension);
+ ivec2 group_thread_id_2 = ivec2((group_index + (kTileDimension2 >> 2)) % kTileDimension, (group_index + (kTileDimension2 >> 2)) / kTileDimension);
+ ivec2 group_thread_id_3 = ivec2((group_index + (kTileDimension2 >> 1)) % kTileDimension, (group_index + (kTileDimension2 >> 1)) / kTileDimension);
+ ivec2 group_thread_id_4 = ivec2((group_index + kTileDimension2 * 3 / 4) % kTileDimension, (group_index + kTileDimension2 * 3 / 4) / kTileDimension);
+
+ store_color_depth(group_thread_id_1, group_top_left + group_thread_id_1);
+ store_color_depth(group_thread_id_2, group_top_left + group_thread_id_2);
+ store_color_depth(group_thread_id_3, group_top_left + group_thread_id_3);
+ store_color_depth(group_thread_id_4, group_top_left + group_thread_id_4);
+ }
+
+ // Wait for group threads to load store data.
+ groupMemoryBarrier();
+ barrier();
+}
+#else
+vec3 load_color(uvec2 screen_pos) {
+ return imageLoad(color_buffer, ivec2(screen_pos)).rgb;
+}
+
+float load_depth(uvec2 screen_pos) {
+ return get_depth(ivec2(screen_pos));
+}
+#endif
+
+/*------------------------------------------------------------------------------
+ VELOCITY
+------------------------------------------------------------------------------*/
+
+void depth_test_min(uvec2 pos, inout float min_depth, inout uvec2 min_pos) {
+ float depth = load_depth(pos);
+
+ if (depth < min_depth) {
+ min_depth = depth;
+ min_pos = pos;
+ }
+}
+
+// Returns velocity with closest depth (3x3 neighborhood)
+void get_closest_pixel_velocity_3x3(in uvec2 group_pos, uvec2 group_top_left, out vec2 velocity) {
+ float min_depth = 1.0;
+ uvec2 min_pos = group_pos;
+
+ depth_test_min(group_pos + kOffsets3x3[0], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[1], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[2], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[3], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[4], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[5], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[6], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[7], min_depth, min_pos);
+ depth_test_min(group_pos + kOffsets3x3[8], min_depth, min_pos);
+
+ // Velocity out
+ velocity = imageLoad(velocity_buffer, ivec2(group_top_left + min_pos)).xy;
+}
+
+/*------------------------------------------------------------------------------
+ HISTORY SAMPLING
+------------------------------------------------------------------------------*/
+
+vec3 sample_catmull_rom_9(sampler2D stex, vec2 uv, vec2 resolution) {
+ // Source: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1
+ // License: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae
+
+ // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding
+ // down the sample location to get the exact center of our "starting" texel. The starting texel will be at
+ // location [1, 1] in the grid, where [0, 0] is the top left corner.
+ vec2 sample_pos = uv * resolution;
+ vec2 texPos1 = floor(sample_pos - 0.5f) + 0.5f;
+
+ // Compute the fractional offset from our starting texel to our original sample location, which we'll
+ // feed into the Catmull-Rom spline function to get our filter weights.
+ vec2 f = sample_pos - texPos1;
+
+ // Compute the Catmull-Rom weights using the fractional offset that we calculated earlier.
+ // These equations are pre-expanded based on our knowledge of where the texels will be located,
+ // which lets us avoid having to evaluate a piece-wise function.
+ vec2 w0 = f * (-0.5f + f * (1.0f - 0.5f * f));
+ vec2 w1 = 1.0f + f * f * (-2.5f + 1.5f * f);
+ vec2 w2 = f * (0.5f + f * (2.0f - 1.5f * f));
+ vec2 w3 = f * f * (-0.5f + 0.5f * f);
+
+ // Work out weighting factors and sampling offsets that will let us use bilinear filtering to
+ // simultaneously evaluate the middle 2 samples from the 4x4 grid.
+ vec2 w12 = w1 + w2;
+ vec2 offset12 = w2 / (w1 + w2);
+
+ // Compute the final UV coordinates we'll use for sampling the texture
+ vec2 texPos0 = texPos1 - 1.0f;
+ vec2 texPos3 = texPos1 + 2.0f;
+ vec2 texPos12 = texPos1 + offset12;
+
+ texPos0 /= resolution;
+ texPos3 /= resolution;
+ texPos12 /= resolution;
+
+ vec3 result = vec3(0.0f, 0.0f, 0.0f);
+
+ result += textureLod(stex, vec2(texPos0.x, texPos0.y), 0.0).xyz * w0.x * w0.y;
+ result += textureLod(stex, vec2(texPos12.x, texPos0.y), 0.0).xyz * w12.x * w0.y;
+ result += textureLod(stex, vec2(texPos3.x, texPos0.y), 0.0).xyz * w3.x * w0.y;
+
+ result += textureLod(stex, vec2(texPos0.x, texPos12.y), 0.0).xyz * w0.x * w12.y;
+ result += textureLod(stex, vec2(texPos12.x, texPos12.y), 0.0).xyz * w12.x * w12.y;
+ result += textureLod(stex, vec2(texPos3.x, texPos12.y), 0.0).xyz * w3.x * w12.y;
+
+ result += textureLod(stex, vec2(texPos0.x, texPos3.y), 0.0).xyz * w0.x * w3.y;
+ result += textureLod(stex, vec2(texPos12.x, texPos3.y), 0.0).xyz * w12.x * w3.y;
+ result += textureLod(stex, vec2(texPos3.x, texPos3.y), 0.0).xyz * w3.x * w3.y;
+
+ return max(result, 0.0f);
+}
+
+/*------------------------------------------------------------------------------
+ HISTORY CLIPPING
+------------------------------------------------------------------------------*/
+
+// Based on "Temporal Reprojection Anti-Aliasing" - https://github.com/playdeadgames/temporal
+vec3 clip_aabb(vec3 aabb_min, vec3 aabb_max, vec3 p, vec3 q) {
+ vec3 r = q - p;
+ vec3 rmax = (aabb_max - p.xyz);
+ vec3 rmin = (aabb_min - p.xyz);
+
+ if (r.x > rmax.x + FLT_MIN)
+ r *= (rmax.x / r.x);
+ if (r.y > rmax.y + FLT_MIN)
+ r *= (rmax.y / r.y);
+ if (r.z > rmax.z + FLT_MIN)
+ r *= (rmax.z / r.z);
+
+ if (r.x < rmin.x - FLT_MIN)
+ r *= (rmin.x / r.x);
+ if (r.y < rmin.y - FLT_MIN)
+ r *= (rmin.y / r.y);
+ if (r.z < rmin.z - FLT_MIN)
+ r *= (rmin.z / r.z);
+
+ return p + r;
+}
+
+// Clip history to the neighbourhood of the current sample
+vec3 clip_history_3x3(uvec2 group_pos, vec3 color_history, vec2 velocity_closest) {
+ // Sample a 3x3 neighbourhood
+ vec3 s1 = load_color(group_pos + kOffsets3x3[0]);
+ vec3 s2 = load_color(group_pos + kOffsets3x3[1]);
+ vec3 s3 = load_color(group_pos + kOffsets3x3[2]);
+ vec3 s4 = load_color(group_pos + kOffsets3x3[3]);
+ vec3 s5 = load_color(group_pos + kOffsets3x3[4]);
+ vec3 s6 = load_color(group_pos + kOffsets3x3[5]);
+ vec3 s7 = load_color(group_pos + kOffsets3x3[6]);
+ vec3 s8 = load_color(group_pos + kOffsets3x3[7]);
+ vec3 s9 = load_color(group_pos + kOffsets3x3[8]);
+
+ // Compute min and max (with an adaptive box size, which greatly reduces ghosting)
+ vec3 color_avg = (s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9) * RPC_9;
+ vec3 color_avg2 = ((s1 * s1) + (s2 * s2) + (s3 * s3) + (s4 * s4) + (s5 * s5) + (s6 * s6) + (s7 * s7) + (s8 * s8) + (s9 * s9)) * RPC_9;
+ float box_size = mix(0.0f, 2.5f, smoothstep(0.02f, 0.0f, length(velocity_closest)));
+ vec3 dev = sqrt(abs(color_avg2 - (color_avg * color_avg))) * box_size;
+ vec3 color_min = color_avg - dev;
+ vec3 color_max = color_avg + dev;
+
+ // Variance clipping
+ vec3 color = clip_aabb(color_min, color_max, clamp(color_avg, color_min, color_max), color_history);
+
+ // Clamp to prevent NaNs
+ color = clamp(color, FLT_MIN, FLT_MAX);
+
+ return color;
+}
+
+/*------------------------------------------------------------------------------
+ TAA
+------------------------------------------------------------------------------*/
+
+const vec3 lumCoeff = vec3(0.299f, 0.587f, 0.114f);
+
+float luminance(vec3 color) {
+ return max(dot(color, lumCoeff), 0.0001f);
+}
+
+float get_factor_disocclusion(vec2 uv_reprojected, vec2 velocity) {
+ vec2 velocity_previous = imageLoad(last_velocity_buffer, ivec2(uv_reprojected * params.resolution)).xy;
+ vec2 velocity_texels = velocity * params.resolution;
+ vec2 prev_velocity_texels = velocity_previous * params.resolution;
+ float disocclusion = length(prev_velocity_texels - velocity_texels) - params.disocclusion_threshold;
+ return clamp(disocclusion * params.disocclusion_scale, 0.0, 1.0);
+}
+
+vec3 temporal_antialiasing(uvec2 pos_group_top_left, uvec2 pos_group, uvec2 pos_screen, vec2 uv, sampler2D tex_history) {
+ // Get the velocity of the current pixel
+ vec2 velocity = imageLoad(velocity_buffer, ivec2(pos_screen)).xy;
+
+ // Get reprojected uv
+ vec2 uv_reprojected = uv - velocity;
+
+ // Get input color
+ vec3 color_input = load_color(pos_group);
+
+ // Get history color (catmull-rom reduces a lot of the blurring that you get under motion)
+ vec3 color_history = sample_catmull_rom_9(tex_history, uv_reprojected, params.resolution).rgb;
+
+ // Clip history to the neighbourhood of the current sample (fixes a lot of the ghosting).
+ vec2 velocity_closest = vec2(0.0); // This is best done by using the velocity with the closest depth.
+ get_closest_pixel_velocity_3x3(pos_group, pos_group_top_left, velocity_closest);
+ color_history = clip_history_3x3(pos_group, color_history, velocity_closest);
+
+ // Compute blend factor
+ float blend_factor = RPC_16; // We want to be able to accumulate as many jitter samples as we generated, that is, 16.
+ {
+ // If re-projected UV is out of screen, converge to current color immediatel
+ float factor_screen = any(lessThan(uv_reprojected, vec2(0.0))) || any(greaterThan(uv_reprojected, vec2(1.0))) ? 1.0 : 0.0;
+
+ // Increase blend factor when there is disocclusion (fixes a lot of the remaining ghosting).
+ float factor_disocclusion = get_factor_disocclusion(uv_reprojected, velocity);
+
+ // Add to the blend factor
+ blend_factor = clamp(blend_factor + factor_screen + factor_disocclusion, 0.0, 1.0);
+ }
+
+ // Resolve
+ vec3 color_resolved = vec3(0.0);
+ {
+ // Tonemap
+ color_history = reinhard(color_history);
+ color_input = reinhard(color_input);
+
+ // Reduce flickering
+ float lum_color = luminance(color_input);
+ float lum_history = luminance(color_history);
+ float diff = abs(lum_color - lum_history) / max(lum_color, max(lum_history, 1.001));
+ diff = 1.0 - diff;
+ diff = diff * diff;
+ blend_factor = mix(0.0, blend_factor, diff);
+
+ // Lerp/blend
+ color_resolved = mix(color_history, color_input, blend_factor);
+
+ // Inverse tonemap
+ color_resolved = reinhard_inverse(color_resolved);
+ }
+
+ return color_resolved;
+}
+
+void main() {
+#ifdef USE_SUBGROUPS
+ populate_group_shared_memory(gl_WorkGroupID.xy, gl_LocalInvocationIndex);
+#endif
+
+ // Out of bounds check
+ if (any(greaterThanEqual(vec2(gl_GlobalInvocationID.xy), params.resolution))) {
+ return;
+ }
+
+#ifdef USE_SUBGROUPS
+ const uvec2 pos_group = gl_LocalInvocationID.xy;
+ const uvec2 pos_group_top_left = gl_WorkGroupID.xy * kGroupSize - kBorderSize;
+#else
+ const uvec2 pos_group = gl_GlobalInvocationID.xy;
+ const uvec2 pos_group_top_left = uvec2(0, 0);
+#endif
+ const uvec2 pos_screen = gl_GlobalInvocationID.xy;
+ const vec2 uv = (gl_GlobalInvocationID.xy + 0.5f) / params.resolution;
+
+ vec3 result = temporal_antialiasing(pos_group_top_left, pos_group, pos_screen, uv, history_buffer);
+ imageStore(output_buffer, ivec2(gl_GlobalInvocationID.xy), vec4(result, 1.0));
+}
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index a2a4c91894..eee609fb48 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -186,12 +186,31 @@ void main() {
float sdf = -1.0;
if (params.shape == 0) {
- //Ellipsoid
+ // Ellipsoid
// https://www.shadertoy.com/view/tdS3DG
float k0 = length(local_pos.xyz / params.extents);
float k1 = length(local_pos.xyz / (params.extents * params.extents));
sdf = k0 * (k0 - 1.0) / k1;
} else if (params.shape == 1) {
+ // Cone
+ // https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
+
+ // Compute the cone angle automatically to fit within the volume's extents.
+ float inv_height = 1.0 / max(0.001, params.extents.y);
+ float radius = 1.0 / max(0.001, (min(params.extents.x, params.extents.z) * 0.5));
+ float hypotenuse = sqrt(radius * radius + inv_height * inv_height);
+ float rsin = radius / hypotenuse;
+ float rcos = inv_height / hypotenuse;
+ vec2 c = vec2(rsin, rcos);
+
+ float q = length(local_pos.xz);
+ sdf = max(dot(c, vec2(q, local_pos.y - params.extents.y)), -params.extents.y - local_pos.y);
+ } else if (params.shape == 2) {
+ // Cylinder
+ // https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
+ vec2 d = abs(vec2(length(local_pos.xz), local_pos.y)) - vec2(min(params.extents.x, params.extents.z), params.extents.y);
+ sdf = min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
+ } else if (params.shape == 3) {
// Box
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
vec3 q = abs(local_pos.xyz) - params.extents;
@@ -199,7 +218,7 @@ void main() {
}
float cull_mask = 1.0; //used to cull cells that do not contribute
- if (params.shape <= 1) {
+ if (params.shape <= 3) {
#ifndef SDF_USED
cull_mask = 1.0 - smoothstep(-0.1, 0.0, sdf);
#endif
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index 27f0c5f273..096d371b8d 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -955,7 +955,7 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag
//value=E.value.default_value;
} else {
//zero because it was not provided
- if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
//colors must be set as black, with alpha as 1.0
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
} else {
@@ -1090,8 +1090,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
case ShaderLanguage::TYPE_USAMPLER2D:
case ShaderLanguage::TYPE_SAMPLER2D: {
switch (p_texture_uniforms[i].hint) {
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK:
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_BLACK);
} break;
case ShaderLanguage::ShaderNode::Uniform::HINT_ANISOTROPY: {
@@ -1111,8 +1110,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
case ShaderLanguage::TYPE_SAMPLERCUBE: {
switch (p_texture_uniforms[i].hint) {
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK:
- case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO: {
+ case ShaderLanguage::ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
rd_texture = texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_CUBEMAP_BLACK);
} break;
default: {
@@ -1152,7 +1150,7 @@ void MaterialData::update_textures(const HashMap<StringName, Variant> &p_paramet
p_textures[k++] = rd_texture;
}
} else {
- bool srgb = p_use_linear_color && (p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_ALBEDO || p_texture_uniforms[i].hint == ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO);
+ bool srgb = p_use_linear_color && p_texture_uniforms[i].use_color;
for (int j = 0; j < textures.size(); j++) {
Texture *tex = TextureStorage::get_singleton()->get_texture(textures[j]);
@@ -1979,8 +1977,8 @@ void MaterialStorage::global_variable_set(const StringName &p_name, const Varian
} else {
//texture
MaterialStorage *material_storage = MaterialStorage::get_singleton();
- for (RBSet<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) {
- Material *material = material_storage->get_material(E->get());
+ for (const RID &E : gv.texture_materials) {
+ Material *material = material_storage->get_material(E);
ERR_CONTINUE(!material);
material_storage->_material_queue_update(material, false, true);
}
@@ -2011,8 +2009,8 @@ void MaterialStorage::global_variable_set_override(const StringName &p_name, con
} else {
//texture
MaterialStorage *material_storage = MaterialStorage::get_singleton();
- for (RBSet<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) {
- Material *material = material_storage->get_material(E->get());
+ for (const RID &E : gv.texture_materials) {
+ Material *material = material_storage->get_material(E);
ERR_CONTINUE(!material);
material_storage->_material_queue_update(material, false, true);
}
@@ -2267,7 +2265,7 @@ void MaterialStorage::shader_free(RID p_rid) {
//make material unreference this
while (shader->owners.size()) {
- material_set_shader(shader->owners.front()->get()->self, RID());
+ material_set_shader((*shader->owners.begin())->self, RID());
}
//clear data if exists
@@ -2305,8 +2303,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
shader->data = nullptr;
}
- for (RBSet<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
- Material *material = E->get();
+ for (Material *E : shader->owners) {
+ Material *material = E;
material->shader_type = new_type;
if (material->data) {
memdelete(material->data);
@@ -2322,8 +2320,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
shader->type = SHADER_TYPE_MAX; //invalid
}
- for (RBSet<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
- Material *material = E->get();
+ for (Material *E : shader->owners) {
+ Material *material = E;
if (shader->data) {
material->data = material_get_data_request_function(new_type)(shader->data);
material->data->self = material->self;
@@ -2346,8 +2344,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
shader->data->set_code(p_code);
}
- for (RBSet<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
- Material *material = E->get();
+ for (Material *E : shader->owners) {
+ Material *material = E;
material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
@@ -2388,8 +2386,8 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin
if (shader->data) {
shader->data->set_default_texture_param(p_name, p_texture, p_index);
}
- for (RBSet<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
- Material *material = E->get();
+ for (Material *E : shader->owners) {
+ Material *material = E;
_material_queue_update(material, false, true);
}
}
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h
index 7d4db49f78..f83df05355 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h
@@ -77,7 +77,7 @@ struct Shader {
String code;
ShaderType type;
HashMap<StringName, HashMap<int, RID>> default_texture_parameter;
- RBSet<Material *> owners;
+ HashSet<Material *> owners;
};
/* Material structs */
@@ -137,7 +137,7 @@ struct GlobalVariables {
BUFFER_DIRTY_REGION_SIZE = 1024
};
struct Variable {
- RBSet<RID> texture_materials; // materials using this
+ HashSet<RID> texture_materials; // materials using this
RS::GlobalVariableType type;
Variant value;
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index fa051c92ed..1e0d67f269 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -215,8 +215,8 @@ void MeshStorage::mesh_free(RID p_rid) {
ERR_PRINT("deleting mesh with active instances");
}
if (mesh->shadow_owners.size()) {
- for (RBSet<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) {
- Mesh *shadow_owner = E->get();
+ for (Mesh *E : mesh->shadow_owners) {
+ Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
}
@@ -431,8 +431,8 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
- for (RBSet<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) {
- Mesh *shadow_owner = E->get();
+ for (Mesh *E : mesh->shadow_owners) {
+ Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
}
@@ -742,8 +742,8 @@ void MeshStorage::mesh_clear(RID p_mesh) {
mesh->has_bone_weights = false;
mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
- for (RBSet<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) {
- Mesh *shadow_owner = E->get();
+ for (Mesh *E : mesh->shadow_owners) {
+ Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
}
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
index d90bb2f128..7ce019cf98 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
@@ -141,7 +141,7 @@ struct Mesh {
List<MeshInstance *> instances;
RID shadow_mesh;
- RBSet<Mesh *> shadow_owners;
+ HashSet<Mesh *> shadow_owners;
RendererStorage::Dependency dependency;
};
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index 1701b56b0b..58a96ed1f9 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -540,11 +540,8 @@ void ParticlesStorage::particles_emit(RID p_particles, const Transform3D &p_tran
_particles_allocate_emission_buffer(particles);
}
- if (particles->inactive) {
- //in case it was inactive, make active again
- particles->inactive = false;
- particles->inactive_time = 0;
- }
+ particles->inactive = false;
+ particles->inactive_time = 0;
int32_t idx = particles->emission_buffer->particle_count;
if (idx < particles->emission_buffer->particle_max) {
@@ -838,8 +835,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
}
uint32_t collision_3d_textures_used = 0;
- for (const RBSet<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
- ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(E->get());
+ for (const RID &E : p_particles->collisions) {
+ ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(E);
if (!pci || !pci->active) {
continue;
}
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
index eb55db19fb..115633d17a 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
@@ -224,7 +224,7 @@ struct Particles {
ParticleEmissionBuffer *emission_buffer = nullptr;
RID emission_storage_buffer;
- RBSet<RID> collisions;
+ HashSet<RID> collisions;
RendererStorage::Dependency dependency;
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 7d4808f936..329c23bad0 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -2075,7 +2075,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
//until we implement support for HDR monitors (and render target is attached to screen), this is enough.
rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
- rt->image_format = rt->flags[RENDER_TARGET_TRANSPARENT] ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8;
+ rt->image_format = rt->is_transparent ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8;
RD::TextureFormat rd_format;
RD::TextureView rd_view;
@@ -2127,7 +2127,7 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
//so transparent can be supported
RD::TextureView view;
view.format_override = rt->color_format;
- if (!rt->flags[RENDER_TARGET_TRANSPARENT]) {
+ if (!rt->is_transparent) {
view.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
}
tex->rd_texture = RD::get_singleton()->texture_create_shared(view, rt->color);
@@ -2194,9 +2194,6 @@ RID TextureStorage::render_target_create() {
render_target.was_used = false;
render_target.clear_requested = false;
- for (int i = 0; i < RENDER_TARGET_FLAG_MAX; i++) {
- render_target.flags[i] = false;
- }
_update_render_target(&render_target);
return render_target_owner.make_rid(render_target);
}
@@ -2240,13 +2237,16 @@ RID TextureStorage::render_target_get_texture(RID p_render_target) {
void TextureStorage::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
}
-void TextureStorage::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) {
+void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_is_transparent) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND(!rt);
- rt->flags[p_flag] = p_value;
+ rt->is_transparent = p_is_transparent;
_update_render_target(rt);
}
+void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_value) {
+}
+
bool TextureStorage::render_target_was_used(RID p_render_target) {
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
ERR_FAIL_COND_V(!rt, false);
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 029816cbda..901f764085 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -124,7 +124,7 @@ public:
RID proxy_to;
Vector<RID> proxies;
- RBSet<RID> lightmap_users;
+ HashSet<RID> lightmap_users;
RS::TextureDetectCallback detect_3d_callback = nullptr;
void *detect_3d_callback_ud = nullptr;
@@ -207,7 +207,7 @@ struct RenderTarget {
RD::DataFormat color_format_srgb = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
Image::Format image_format = Image::FORMAT_L8;
- bool flags[RendererTextureStorage::RENDER_TARGET_FLAG_MAX];
+ bool is_transparent = false;
bool sdf_enabled = false;
@@ -525,7 +525,8 @@ public:
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override;
virtual RID render_target_get_texture(RID p_render_target) override;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override;
- virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override;
+ virtual void render_target_set_transparent(RID p_render_target, bool p_is_transparent) override;
+ virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) override;
virtual bool render_target_was_used(RID p_render_target) override;
virtual void render_target_set_as_unused(RID p_render_target) override;
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
index 43d5b07869..b773ed61f4 100644
--- a/servers/rendering/renderer_scene.h
+++ b/servers/rendering/renderer_scene.h
@@ -194,7 +194,7 @@ public:
virtual RID render_buffers_create() = 0;
- virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) = 0;
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0;
virtual void gi_set_use_half_resolution(bool p_enable) = 0;
@@ -211,7 +211,7 @@ public:
int info[RS::VIEWPORT_RENDER_INFO_TYPE_MAX][RS::VIEWPORT_RENDER_INFO_MAX] = {};
};
- virtual void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info = nullptr) = 0;
+ virtual void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, bool p_use_taa, float p_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info = nullptr) = 0;
virtual void update() = 0;
virtual void render_probes() = 0;
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 37bbab86ff..6f427272b5 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -562,8 +562,8 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
case RS::INSTANCE_LIGHTMAP: {
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data);
//erase dependencies, since no longer a lightmap
- while (lightmap_data->users.front()) {
- instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0);
+ while (lightmap_data->users.begin()) {
+ instance_geometry_set_lightmap((*lightmap_data->users.begin())->self, RID(), Rect2(), 0);
}
scene_render->free(lightmap_data->instance);
} break;
@@ -653,8 +653,8 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr());
}
- for (RBSet<Instance *>::Element *E = instance->visibility_dependencies.front(); E; E = E->next()) {
- Instance *dep_instance = E->get();
+ for (Instance *E : instance->visibility_dependencies) {
+ Instance *dep_instance = E;
ERR_CONTINUE(dep_instance->array_index == -1);
ERR_CONTINUE(dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index != -1);
dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = instance->array_index;
@@ -1292,15 +1292,15 @@ void RendererSceneCull::instance_set_visibility_parent(RID p_instance, RID p_par
bool RendererSceneCull::_update_instance_visibility_depth(Instance *p_instance) {
bool cycle_detected = false;
- RBSet<Instance *> traversed_nodes;
+ HashSet<Instance *> traversed_nodes;
{
Instance *instance = p_instance;
while (instance) {
if (!instance->visibility_dependencies.is_empty()) {
uint32_t depth = 0;
- for (RBSet<Instance *>::Element *E = instance->visibility_dependencies.front(); E; E = E->next()) {
- depth = MAX(depth, E->get()->visibility_dependencies_depth);
+ for (const Instance *E : instance->visibility_dependencies) {
+ depth = MAX(depth, E->visibility_dependencies_depth);
}
instance->visibility_dependencies_depth = depth + 1;
} else {
@@ -1559,8 +1559,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
//erase dependencies, since no longer a lightmap
- for (RBSet<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
- Instance *geom = E->get();
+ for (Instance *E : lightmap_data->geometries) {
+ Instance *geom = E;
_instance_queue_update(geom, true, false);
}
}
@@ -1574,8 +1574,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
//make sure lights are updated if it casts shadow
if (geom->can_cast_shadows) {
- for (RBSet<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ for (const Instance *E : geom->lights) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data);
light->shadow_dirty = true;
}
}
@@ -1632,8 +1632,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
idata.parent_array_index = p_instance->visibility_parent ? p_instance->visibility_parent->array_index : -1;
idata.visibility_index = p_instance->visibility_index;
- for (RBSet<Instance *>::Element *E = p_instance->visibility_dependencies.front(); E; E = E->next()) {
- Instance *dep_instance = E->get();
+ for (Instance *E : p_instance->visibility_dependencies) {
+ Instance *dep_instance = E;
if (dep_instance->array_index != -1) {
dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = p_instance->array_index;
}
@@ -1800,8 +1800,8 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {
swapped_instance->scenario->instance_visibility[swapped_instance->visibility_index].array_index = swapped_instance->array_index;
}
- for (RBSet<Instance *>::Element *E = swapped_instance->visibility_dependencies.front(); E; E = E->next()) {
- Instance *dep_instance = E->get();
+ for (Instance *E : swapped_instance->visibility_dependencies) {
+ Instance *dep_instance = E;
if (dep_instance != p_instance && dep_instance->array_index != -1) {
dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = swapped_instance->array_index;
}
@@ -1824,8 +1824,8 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {
scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, nullptr, 0);
}
- for (RBSet<Instance *>::Element *E = p_instance->visibility_dependencies.front(); E; E = E->next()) {
- Instance *dep_instance = E->get();
+ for (Instance *E : p_instance->visibility_dependencies) {
+ Instance *dep_instance = E;
if (dep_instance->array_index != -1) {
dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = -1;
if ((1 << dep_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
@@ -1923,8 +1923,8 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance)
float accum_blend = 0.0;
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
- for (RBSet<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) {
- Instance *lightmap = E->get();
+ for (Instance *E : geom->lightmap_captures) {
+ Instance *lightmap = E;
bool interior = RSG::light_storage->lightmap_is_interior(lightmap->base);
@@ -2433,12 +2433,17 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
return animated_material_found;
}
-void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info) {
+void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, bool p_use_taa, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RenderInfo *r_render_info) {
#ifndef _3D_DISABLED
Camera *camera = camera_owner.get_or_null(p_camera);
ERR_FAIL_COND(!camera);
+ Vector2 jitter;
+ if (p_use_taa) {
+ jitter = taa_jitter_array[RSG::rasterizer->get_frame_number() % TAA_JITTER_COUNT] / p_viewport_size;
+ }
+
RendererSceneRender::CameraData camera_data;
// Setup Camera(s)
@@ -2479,7 +2484,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_
} break;
}
- camera_data.set_camera(transform, projection, is_orthogonal, vaspect);
+ camera_data.set_camera(transform, projection, is_orthogonal, vaspect, jitter);
} else {
// Setup our camera for our XR interface.
// We can support multiple views here each with their own camera
@@ -2501,7 +2506,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_
}
if (view_count == 1) {
- camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect);
+ camera_data.set_camera(transforms[0], projections[0], false, camera->vaspect, jitter);
} else if (view_count == 2) {
camera_data.set_multiview_camera(view_count, transforms, projections, false, camera->vaspect);
} else {
@@ -2744,8 +2749,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
uint32_t idx = 0;
- for (RBSet<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ for (const Instance *E : geom->lights) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data);
instance_pair_buffer[idx++] = light->instance;
if (idx == MAX_INSTANCE_PAIRS) {
break;
@@ -2767,8 +2772,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
uint32_t idx = 0;
- for (RBSet<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) {
- InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
+ for (const Instance *E : geom->reflection_probes) {
+ InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->base_data);
instance_pair_buffer[idx++] = reflection_probe->instance;
if (idx == MAX_INSTANCE_PAIRS) {
@@ -2784,8 +2789,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
uint32_t idx = 0;
- for (RBSet<Instance *>::Element *E = geom->decals.front(); E; E = E->next()) {
- InstanceDecalData *decal = static_cast<InstanceDecalData *>(E->get()->base_data);
+ for (const Instance *E : geom->decals) {
+ InstanceDecalData *decal = static_cast<InstanceDecalData *>(E->base_data);
instance_pair_buffer[idx++] = decal->instance;
if (idx == MAX_INSTANCE_PAIRS) {
@@ -2799,8 +2804,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
if (idata.flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
uint32_t idx = 0;
- for (RBSet<Instance *>::Element *E = geom->voxel_gi_instances.front(); E; E = E->next()) {
- InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->get()->base_data);
+ for (const Instance *E : geom->voxel_gi_instances) {
+ InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->base_data);
instance_pair_buffer[idx++] = voxel_gi->probe_instance;
if (idx == MAX_INSTANCE_PAIRS) {
@@ -3216,12 +3221,18 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
/* PROCESS GEOMETRY AND DRAW SCENE */
RID occluders_tex;
+ const RendererSceneRender::CameraData *prev_camera_data = p_camera_data;
if (p_viewport.is_valid()) {
occluders_tex = RSG::viewport->viewport_get_occluder_debug_texture(p_viewport);
+ prev_camera_data = RSG::viewport->viewport_get_prev_camera_data(p_viewport);
}
RENDER_TIMESTAMP("Render 3D Scene");
- scene_render->render_scene(p_render_buffers, p_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
+ scene_render->render_scene(p_render_buffers, p_camera_data, prev_camera_data, scene_cull_result.geometry_instances, scene_cull_result.light_instances, scene_cull_result.reflections, scene_cull_result.voxel_gi_instances, scene_cull_result.decals, scene_cull_result.lightmaps, scene_cull_result.fog_volumes, p_environment, camera_effects, p_shadow_atlas, occluders_tex, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass, p_screen_mesh_lod_threshold, render_shadow_data, max_shadows_used, render_sdfgi_data, cull.sdfgi.region_count, &sdfgi_update_data, r_render_info);
+
+ if (p_viewport.is_valid()) {
+ RSG::viewport->viewport_set_prev_camera_data(p_viewport, p_camera_data);
+ }
for (uint32_t i = 0; i < max_shadows_used; i++) {
render_shadow_data[i].instances.clear();
@@ -3271,7 +3282,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario,
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), CameraMatrix(), true, false);
- scene_render->render_scene(p_render_buffers, &camera_data, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
+ scene_render->render_scene(p_render_buffers, &camera_data, nullptr, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
}
@@ -3420,8 +3431,8 @@ void RendererSceneCull::render_probes() {
const RID *instance_caches = probe->light_instances.ptr();
int idx = 0; //must count visible lights
- for (RBSet<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) {
- Instance *instance = E->get();
+ for (Instance *E : probe->lights) {
+ Instance *instance = E;
InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
if (!instance->visible) {
continue;
@@ -3502,8 +3513,8 @@ void RendererSceneCull::render_probes() {
RID *instance_caches = probe->light_instances.ptrw();
int idx = 0; //must count visible lights
- for (RBSet<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) {
- Instance *instance = E->get();
+ for (Instance *E : probe->lights) {
+ Instance *instance = E;
InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
if (!instance->visible) {
continue;
@@ -3557,8 +3568,8 @@ void RendererSceneCull::render_probes() {
RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
- for (RBSet<Instance *>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) {
- Instance *ins = E->get();
+ for (Instance *E : probe->dynamic_geometries) {
+ Instance *ins = E;
if (!ins->visible) {
continue;
}
@@ -3566,8 +3577,8 @@ void RendererSceneCull::render_probes() {
if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY)) {
uint32_t idx = 0;
- for (RBSet<Instance *>::Element *F = geom->voxel_gi_instances.front(); F; F = F->next()) {
- InstanceVoxelGIData *voxel_gi2 = static_cast<InstanceVoxelGIData *>(F->get()->base_data);
+ for (const Instance *F : geom->voxel_gi_instances) {
+ InstanceVoxelGIData *voxel_gi2 = static_cast<InstanceVoxelGIData *>(F->base_data);
instance_pair_buffer[idx++] = voxel_gi2->probe_instance;
if (idx == MAX_INSTANCE_PAIRS) {
@@ -3592,8 +3603,8 @@ void RendererSceneCull::render_probes() {
}
void RendererSceneCull::render_particle_colliders() {
- while (heightfield_particle_colliders_update_list.front()) {
- Instance *hfpc = heightfield_particle_colliders_update_list.front()->get();
+ while (heightfield_particle_colliders_update_list.begin()) {
+ Instance *hfpc = *heightfield_particle_colliders_update_list.begin();
if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::particles_storage->particles_collision_is_heightfield(hfpc->base)) {
//update heightfield
@@ -3625,7 +3636,7 @@ void RendererSceneCull::render_particle_colliders() {
scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, scene_cull_result.geometry_instances);
}
- heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front());
+ heightfield_particle_colliders_update_list.remove(heightfield_particle_colliders_update_list.begin());
}
}
@@ -3823,8 +3834,8 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
if (can_cast_shadows != geom->can_cast_shadows) {
//ability to cast shadows change, let lights now
- for (RBSet<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
- InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
+ for (const Instance *E : geom->lights) {
+ InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data);
light->shadow_dirty = true;
}
@@ -3993,6 +4004,17 @@ void RendererSceneCull::set_scene_render(RendererSceneRender *p_scene_render) {
geometry_instance_pair_mask = scene_render->geometry_instance_get_pair_mask();
}
+float get_halton_value(int index, int base) {
+ float f = 1;
+ float r = 0;
+ while (index > 0) {
+ f = f / static_cast<float>(base);
+ r = r + f * (index % base);
+ index = index / base;
+ }
+ return r * 2.0f - 1.0f;
+};
+
RendererSceneCull::RendererSceneCull() {
render_pass = 1;
singleton = this;
@@ -4017,6 +4039,12 @@ RendererSceneCull::RendererSceneCull() {
thread_cull_threshold = GLOBAL_GET("rendering/limits/spatial_indexer/threaded_cull_minimum_instances");
thread_cull_threshold = MAX(thread_cull_threshold, (uint32_t)RendererThreadPool::singleton->thread_work_pool.get_thread_count()); //make sure there is at least one thread per CPU
+ taa_jitter_array.resize(TAA_JITTER_COUNT);
+ for (int i = 0; i < TAA_JITTER_COUNT; i++) {
+ taa_jitter_array[i].x = get_halton_value(i, 2);
+ taa_jitter_array[i].y = get_halton_value(i, 3);
+ }
+
dummy_occlusion_culling = memnew(RendererSceneOcclusionCull);
}
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index c5325ef30a..d1d3484871 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -443,7 +443,7 @@ public:
float visibility_range_end_margin = 0.0f;
RS::VisibilityRangeFadeMode visibility_range_fade_mode = RS::VISIBILITY_RANGE_FADE_DISABLED;
Instance *visibility_parent = nullptr;
- RBSet<Instance *> visibility_dependencies;
+ HashSet<Instance *> visibility_dependencies;
uint32_t visibility_dependencies_depth = 0;
float transparency = 0.0f;
Scenario *scenario = nullptr;
@@ -579,16 +579,16 @@ public:
struct InstanceGeometryData : public InstanceBaseData {
RendererSceneRender::GeometryInstance *geometry_instance = nullptr;
- RBSet<Instance *> lights;
+ HashSet<Instance *> lights;
bool can_cast_shadows;
bool material_is_animated;
uint32_t projector_count = 0;
uint32_t softshadow_count = 0;
- RBSet<Instance *> decals;
- RBSet<Instance *> reflection_probes;
- RBSet<Instance *> voxel_gi_instances;
- RBSet<Instance *> lightmap_captures;
+ HashSet<Instance *> decals;
+ HashSet<Instance *> reflection_probes;
+ HashSet<Instance *> voxel_gi_instances;
+ HashSet<Instance *> lightmap_captures;
InstanceGeometryData() {
can_cast_shadows = true;
@@ -599,7 +599,7 @@ public:
struct InstanceReflectionProbeData : public InstanceBaseData {
Instance *owner = nullptr;
- RBSet<Instance *> geometries;
+ HashSet<Instance *> geometries;
RID instance;
SelfList<InstanceReflectionProbeData> update_list;
@@ -616,7 +616,7 @@ public:
Instance *owner = nullptr;
RID instance;
- RBSet<Instance *> geometries;
+ HashSet<Instance *> geometries;
InstanceDecalData() {
}
@@ -654,7 +654,7 @@ public:
bool uses_projector = false;
bool uses_softshadow = false;
- RBSet<Instance *> geometries;
+ HashSet<Instance *> geometries;
Instance *baked_light = nullptr;
@@ -673,10 +673,10 @@ public:
struct InstanceVoxelGIData : public InstanceBaseData {
Instance *owner = nullptr;
- RBSet<Instance *> geometries;
- RBSet<Instance *> dynamic_geometries;
+ HashSet<Instance *> geometries;
+ HashSet<Instance *> dynamic_geometries;
- RBSet<Instance *> lights;
+ HashSet<Instance *> lights;
struct LightCache {
RS::LightType type;
@@ -713,8 +713,8 @@ public:
struct InstanceLightmapData : public InstanceBaseData {
RID instance;
- RBSet<Instance *> geometries;
- RBSet<Instance *> users;
+ HashSet<Instance *> geometries;
+ HashSet<Instance *> users;
InstanceLightmapData() {
}
@@ -779,7 +779,7 @@ public:
}
};
- RBSet<Instance *> heightfield_particle_colliders_update_list;
+ HashSet<Instance *> heightfield_particle_colliders_update_list;
PagedArrayPool<Instance *> instance_cull_page_pool;
PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool;
@@ -923,6 +923,9 @@ public:
uint32_t geometry_instance_pair_mask = 0; // used in traditional forward, unnecessary on clustered
+ const int TAA_JITTER_COUNT = 16;
+ LocalVector<Vector2> taa_jitter_array;
+
virtual RID instance_allocate();
virtual void instance_initialize(RID p_rid);
@@ -1054,7 +1057,7 @@ public:
void _render_scene(const RendererSceneRender::CameraData *p_camera_data, RID p_render_buffers, RID p_environment, RID p_force_camera_effects, uint32_t p_visible_layers, RID p_scenario, RID p_viewport, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, bool p_using_shadows = true, RenderInfo *r_render_info = nullptr);
void render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas);
- void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RendererScene::RenderInfo *r_render_info = nullptr);
+ void render_camera(RID p_render_buffers, RID p_camera, RID p_scenario, RID p_viewport, Size2 p_viewport_size, bool p_use_taa, float p_screen_mesh_lod_threshold, RID p_shadow_atlas, Ref<XRInterface> &p_xr_interface, RendererScene::RenderInfo *r_render_info = nullptr);
void update_dirty_instances();
void render_particle_colliders();
@@ -1155,7 +1158,7 @@ public:
/* Render Buffers */
PASS0R(RID, render_buffers_create)
- PASS12(render_buffers_configure, RID, RID, int, int, int, int, float, float, RS::ViewportMSAA, RS::ViewportScreenSpaceAA, bool, uint32_t)
+ PASS13(render_buffers_configure, RID, RID, int, int, int, int, float, float, RS::ViewportMSAA, RS::ViewportScreenSpaceAA, bool, bool, uint32_t)
PASS1(gi_set_use_half_resolution, bool)
/* Shadow Atlas */
diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h
index 48412dab68..7198379ade 100644
--- a/servers/rendering/renderer_scene_occlusion_cull.h
+++ b/servers/rendering/renderer_scene_occlusion_cull.h
@@ -161,31 +161,31 @@ public:
static RendererSceneOcclusionCull *get_singleton() { return singleton; }
- void _print_warining() {
- WARN_PRINT_ONCE("Occlusion culling is disabled at build time.");
+ void _print_warning() {
+ WARN_PRINT_ONCE("Occlusion culling is disabled at build-time.");
}
virtual bool is_occluder(RID p_rid) { return false; }
virtual RID occluder_allocate() { return RID(); }
virtual void occluder_initialize(RID p_occluder) {}
- virtual void free_occluder(RID p_occluder) { _print_warining(); }
- virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) { _print_warining(); }
+ virtual void free_occluder(RID p_occluder) { _print_warning(); }
+ virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) { _print_warning(); }
virtual void add_scenario(RID p_scenario) {}
virtual void remove_scenario(RID p_scenario) {}
- virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) { _print_warining(); }
- virtual void scenario_remove_instance(RID p_scenario, RID p_instance) { _print_warining(); }
+ virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) { _print_warning(); }
+ virtual void scenario_remove_instance(RID p_scenario, RID p_instance) { _print_warning(); }
- virtual void add_buffer(RID p_buffer) { _print_warining(); }
- virtual void remove_buffer(RID p_buffer) { _print_warining(); }
+ virtual void add_buffer(RID p_buffer) { _print_warning(); }
+ virtual void remove_buffer(RID p_buffer) { _print_warning(); }
virtual HZBuffer *buffer_get_ptr(RID p_buffer) {
return nullptr;
}
- virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) { _print_warining(); }
- virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) { _print_warining(); }
+ virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) { _print_warning(); }
+ virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) { _print_warning(); }
virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) {}
virtual RID buffer_get_debug_texture(RID p_buffer) {
- _print_warining();
+ _print_warning();
return RID();
}
diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp
index a4d281fac4..600908cf16 100644
--- a/servers/rendering/renderer_scene_render.cpp
+++ b/servers/rendering/renderer_scene_render.cpp
@@ -30,7 +30,7 @@
#include "renderer_scene_render.h"
-void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect) {
+void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) {
view_count = 1;
is_orthogonal = p_is_orthogonal;
vaspect = p_vaspect;
@@ -40,6 +40,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform,
view_offset[0] = Transform3D();
view_projection[0] = p_projection;
+ taa_jitter = p_taa_jitter;
}
void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const CameraMatrix *p_projections, bool p_is_orthogonal, bool p_vaspect) {
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index d43bfb170e..280277c6d8 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -243,12 +243,13 @@ public:
Transform3D view_offset[RendererSceneRender::MAX_RENDER_VIEWS];
CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
+ Vector2 taa_jitter;
- void set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect);
+ void set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2());
void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const CameraMatrix *p_projections, bool p_is_orthogonal, bool p_vaspect);
};
- virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) = 0;
+ virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) = 0;
virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0;
@@ -258,7 +259,7 @@ public:
virtual void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) = 0;
virtual RID render_buffers_create() = 0;
- virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) = 0;
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) = 0;
virtual void gi_set_use_half_resolution(bool p_enable) = 0;
virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_amount, float p_limit) = 0;
diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h
index 7f35d2ca99..bb4acab582 100644
--- a/servers/rendering/renderer_storage.h
+++ b/servers/rendering/renderer_storage.h
@@ -85,8 +85,8 @@ public:
void update_end() { //call after updating dependencies
List<Pair<Dependency *, DependencyTracker *>> to_clean_up;
- for (RBSet<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
- Dependency *dep = E->get();
+ for (Dependency *E : dependencies) {
+ Dependency *dep = E;
HashMap<DependencyTracker *, uint32_t>::Iterator F = dep->instances.find(this);
ERR_CONTINUE(!F);
if (F->value != instance_version) {
@@ -105,8 +105,8 @@ public:
}
void clear() { // clear all dependencies
- for (RBSet<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) {
- Dependency *dep = E->get();
+ for (Dependency *E : dependencies) {
+ Dependency *dep = E;
dep->instances.erase(this);
}
dependencies.clear();
@@ -117,7 +117,7 @@ public:
private:
friend struct Dependency;
uint32_t instance_version = 0;
- RBSet<Dependency *> dependencies;
+ HashSet<Dependency *> dependencies;
};
virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index d612fb4aa7..2e0c4e0f79 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -138,7 +138,7 @@ void RendererViewport::_configure_3d_render_buffers(Viewport *p_viewport) {
p_viewport->internal_size = Size2(render_width, render_height);
- RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, render_width, render_height, width, height, p_viewport->fsr_sharpness, p_viewport->fsr_mipmap_bias, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_debanding, p_viewport->get_view_count());
+ RSG::scene->render_buffers_configure(p_viewport->render_buffers, p_viewport->render_target, render_width, render_height, width, height, p_viewport->fsr_sharpness, p_viewport->fsr_mipmap_bias, p_viewport->msaa, p_viewport->screen_space_aa, p_viewport->use_taa, p_viewport->use_debanding, p_viewport->get_view_count());
}
}
}
@@ -167,7 +167,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) {
}
float screen_mesh_lod_threshold = p_viewport->mesh_lod_threshold / float(p_viewport->size.width);
- RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->self, p_viewport->internal_size, screen_mesh_lod_threshold, p_viewport->shadow_atlas, xr_interface, &p_viewport->render_info);
+ RSG::scene->render_camera(p_viewport->render_buffers, p_viewport->camera, p_viewport->scenario, p_viewport->self, p_viewport->internal_size, p_viewport->use_taa, screen_mesh_lod_threshold, p_viewport->shadow_atlas, xr_interface, &p_viewport->render_info);
RENDER_TIMESTAMP("< Render 3D Scene");
}
@@ -247,15 +247,15 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size);
- for (RBSet<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
- if (!F->get()->enabled) {
+ for (RendererCanvasRender::LightOccluderInstance *F : canvas->occluders) {
+ if (!F->enabled) {
continue;
}
- F->get()->xform_cache = xf * F->get()->xform;
+ F->xform_cache = xf * F->xform;
- if (sdf_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) {
- F->get()->next = occluders;
- occluders = F->get();
+ if (sdf_rect.intersects_transformed(F->xform_cache, F->aabb_cache)) {
+ F->next = occluders;
+ occluders = F;
}
}
}
@@ -281,8 +281,8 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
// Find lights in canvas.
- for (RBSet<RendererCanvasRender::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) {
- RendererCanvasRender::Light *cl = F->get();
+ for (RendererCanvasRender::Light *F : canvas->lights) {
+ RendererCanvasRender::Light *cl = F;
if (cl->enabled && cl->texture.is_valid()) {
//not super efficient..
Size2 tsize = RSG::texture_storage->texture_size_with_proxy(cl->texture);
@@ -313,8 +313,8 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
}
}
- for (RBSet<RendererCanvasRender::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) {
- RendererCanvasRender::Light *cl = F->get();
+ for (RendererCanvasRender::Light *F : canvas->directional_lights) {
+ RendererCanvasRender::Light *cl = F;
if (cl->enabled) {
cl->filter_next_ptr = directional_lights;
directional_lights = cl;
@@ -349,14 +349,14 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size);
- for (RBSet<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
- if (!F->get()->enabled) {
+ for (RendererCanvasRender::LightOccluderInstance *F : canvas->occluders) {
+ if (!F->enabled) {
continue;
}
- F->get()->xform_cache = xf * F->get()->xform;
- if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) {
- F->get()->next = occluders;
- occluders = F->get();
+ F->xform_cache = xf * F->xform;
+ if (shadow_rect.intersects_transformed(F->xform_cache, F->aabb_cache)) {
+ F->next = occluders;
+ occluders = F;
}
}
}
@@ -429,19 +429,19 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size);
- for (RBSet<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
- if (!F->get()->enabled) {
+ for (RendererCanvasRender::LightOccluderInstance *F : canvas->occluders) {
+ if (!F->enabled) {
continue;
}
- F->get()->xform_cache = xf * F->get()->xform;
- Transform2D localizer = F->get()->xform_cache.affine_inverse();
+ F->xform_cache = xf * F->xform;
+ Transform2D localizer = F->xform_cache.affine_inverse();
for (int j = 0; j < point_count; j++) {
xf_points[j] = localizer.xform(points[j]);
}
- if (F->get()->aabb_cache.intersects_filled_polygon(xf_points, point_count)) {
- F->get()->next = occluders;
- occluders = F->get();
+ if (F->aabb_cache.intersects_filled_polygon(xf_points, point_count)) {
+ F->next = occluders;
+ occluders = F;
}
}
}
@@ -866,7 +866,7 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
}
- RSG::texture_storage->render_target_set_flag(viewport->render_target, RendererTextureStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
+ RSG::texture_storage->render_target_set_direct_to_screen(viewport->render_target, p_enable);
viewport->viewport_render_direct_to_screen = p_enable;
// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
@@ -900,6 +900,22 @@ RID RendererViewport::viewport_get_occluder_debug_texture(RID p_viewport) const
return RID();
}
+void RendererViewport::viewport_set_prev_camera_data(RID p_viewport, const RendererSceneRender::CameraData *p_camera_data) {
+ Viewport *viewport = viewport_owner.get_or_null(p_viewport);
+ ERR_FAIL_COND(!viewport);
+ uint64_t frame = RSG::rasterizer->get_frame_number();
+ if (viewport->prev_camera_data_frame != frame) {
+ viewport->prev_camera_data = *p_camera_data;
+ viewport->prev_camera_data_frame = frame;
+ }
+}
+
+const RendererSceneRender::CameraData *RendererViewport::viewport_get_prev_camera_data(RID p_viewport) {
+ const Viewport *viewport = viewport_owner.get_or_null(p_viewport);
+ ERR_FAIL_COND_V(!viewport, nullptr);
+ return &viewport->prev_camera_data;
+}
+
void RendererViewport::viewport_set_disable_2d(RID p_viewport, bool p_disable) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -980,7 +996,7 @@ void RendererViewport::viewport_set_transparent_background(RID p_viewport, bool
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
- RSG::texture_storage->render_target_set_flag(viewport->render_target, RendererTextureStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
+ RSG::texture_storage->render_target_set_transparent(viewport->render_target, p_enabled);
viewport->transparent_bg = p_enabled;
}
@@ -1039,6 +1055,17 @@ void RendererViewport::viewport_set_screen_space_aa(RID p_viewport, RS::Viewport
_configure_3d_render_buffers(viewport);
}
+void RendererViewport::viewport_set_use_taa(RID p_viewport, bool p_use_taa) {
+ Viewport *viewport = viewport_owner.get_or_null(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ if (viewport->use_taa == p_use_taa) {
+ return;
+ }
+ viewport->use_taa = p_use_taa;
+ _configure_3d_render_buffers(viewport);
+}
+
void RendererViewport::viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) {
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
ERR_FAIL_COND(!viewport);
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index da8cf5396c..18385d1613 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -35,6 +35,7 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/renderer_scene.h"
+#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
#include "servers/xr/xr_interface.h"
@@ -66,8 +67,12 @@ public:
RS::ViewportMSAA msaa;
RS::ViewportScreenSpaceAA screen_space_aa;
+ bool use_taa;
bool use_debanding;
+ RendererSceneRender::CameraData prev_camera_data;
+ uint64_t prev_camera_data_frame = 0;
+
bool use_occlusion_culling;
bool occlusion_buffer_dirty;
@@ -233,6 +238,9 @@ public:
RID viewport_get_texture(RID p_viewport) const;
RID viewport_get_occluder_debug_texture(RID p_viewport) const;
+ void viewport_set_prev_camera_data(RID p_viewport, const RendererSceneRender::CameraData *p_camera_data);
+ const RendererSceneRender::CameraData *viewport_get_prev_camera_data(RID p_viewport);
+
void viewport_set_disable_2d(RID p_viewport, bool p_disable);
void viewport_set_disable_environment(RID p_viewport, bool p_disable);
void viewport_set_disable_3d(RID p_viewport, bool p_disable);
@@ -252,6 +260,7 @@ public:
void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);
void viewport_set_screen_space_aa(RID p_viewport, RS::ViewportScreenSpaceAA p_mode);
+ void viewport_set_use_taa(RID p_viewport, bool p_use_taa);
void viewport_set_use_debanding(RID p_viewport, bool p_use_debanding);
void viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling);
void viewport_set_occlusion_rays_per_thread(int p_rays_per_thread);
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index c4538e0776..718f20f80a 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -313,7 +313,11 @@ RID RenderingServerDefault::get_test_cube() {
}
bool RenderingServerDefault::has_os_feature(const String &p_feature) const {
- return RSG::storage->has_os_feature(p_feature);
+ if (RSG::storage) {
+ return RSG::storage->has_os_feature(p_feature);
+ } else {
+ return false;
+ }
}
void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) {
@@ -384,6 +388,8 @@ void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
command_queue(p_create_thread) {
+ RenderingServer::init();
+
create_thread = p_create_thread;
if (!p_create_thread) {
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 9d4059b9df..6008f2b00e 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -616,6 +616,7 @@ public:
FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
FUNC2(viewport_set_msaa, RID, ViewportMSAA)
FUNC2(viewport_set_screen_space_aa, RID, ViewportScreenSpaceAA)
+ FUNC2(viewport_set_use_taa, RID, bool)
FUNC2(viewport_set_use_debanding, RID, bool)
FUNC2(viewport_set_use_occlusion_culling, RID, bool)
FUNC1(viewport_set_occlusion_rays_per_thread, int)
diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp
index c88d9e8222..463b67033d 100644
--- a/servers/rendering/shader_compiler.cpp
+++ b/servers/rendering/shader_compiler.cpp
@@ -289,7 +289,7 @@ String ShaderCompiler::_get_sampler_name(ShaderLanguage::TextureFilter p_filter,
return actions.sampler_array_name + "[" + itos(p_filter + (p_repeat == ShaderLanguage::REPEAT_ENABLE ? ShaderLanguage::FILTER_DEFAULT : 0)) + "]";
}
-void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, RBSet<StringName> &added) {
+void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added) {
int fidx = -1;
for (int i = 0; i < p_node->functions.size(); i++) {
@@ -303,8 +303,8 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str
Vector<StringName> uses_functions;
- for (RBSet<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) {
- uses_functions.push_back(E->get());
+ for (const StringName &E : p_node->functions[fidx].uses_function) {
+ uses_functions.push_back(E);
}
uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced
@@ -571,6 +571,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
texture.name = uniform_name;
texture.hint = uniform.hint;
texture.type = uniform.type;
+ texture.use_color = uniform.use_color;
texture.filter = uniform.filter;
texture.repeat = uniform.repeat;
texture.global = uniform.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL;
@@ -748,7 +749,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
//place functions in actual code
- RBSet<StringName> added_funcs_per_stage[STAGE_MAX];
+ HashSet<StringName> added_funcs_per_stage[STAGE_MAX];
for (int i = 0; i < pnode->functions.size(); i++) {
SL::FunctionNode *fnode = pnode->functions[i].function;
diff --git a/servers/rendering/shader_compiler.h b/servers/rendering/shader_compiler.h
index 85b93c4063..06f42e9f0f 100644
--- a/servers/rendering/shader_compiler.h
+++ b/servers/rendering/shader_compiler.h
@@ -61,6 +61,7 @@ public:
StringName name;
ShaderLanguage::DataType type;
ShaderLanguage::ShaderNode::Uniform::Hint hint;
+ bool use_color = false;
ShaderLanguage::TextureFilter filter;
ShaderLanguage::TextureRepeat repeat;
bool global;
@@ -103,20 +104,20 @@ private:
String _get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat);
- void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, RBSet<StringName> &added);
+ void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added);
String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_scope = true);
const ShaderLanguage::ShaderNode *shader = nullptr;
const ShaderLanguage::FunctionNode *function = nullptr;
StringName current_func_name;
StringName time_name;
- RBSet<StringName> texture_functions;
+ HashSet<StringName> texture_functions;
- RBSet<StringName> used_name_defines;
- RBSet<StringName> used_flag_pointers;
- RBSet<StringName> used_rmode_defines;
- RBSet<StringName> internal_functions;
- RBSet<StringName> fragment_varyings;
+ HashSet<StringName> used_name_defines;
+ HashSet<StringName> used_flag_pointers;
+ HashSet<StringName> used_rmode_defines;
+ HashSet<StringName> internal_functions;
+ HashSet<StringName> fragment_varyings;
DefaultIdentifierActions actions;
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 8a3ab92714..ad9b51ac0c 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -190,13 +190,11 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"OUT",
"INOUT",
"RENDER_MODE",
- "HINT_WHITE_TEXTURE",
- "HINT_BLACK_TEXTURE",
+ "SOURCE_COLOR",
+ "HINT_DEFAULT_WHITE_TEXTURE",
+ "HINT_DEFAULT_BLACK_TEXTURE",
"HINT_NORMAL_TEXTURE",
"HINT_ANISOTROPY_TEXTURE",
- "HINT_ALBEDO_TEXTURE",
- "HINT_BLACK_ALBEDO_TEXTURE",
- "HINT_COLOR",
"HINT_RANGE",
"HINT_INSTANCE_INDEX",
"FILTER_NEAREST",
@@ -344,17 +342,15 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
// hints
+ { TK_HINT_SOURCE_COLOR, "source_color", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_RANGE, "hint_range", CF_UNSPECIFIED, {}, {} },
- { TK_HINT_COLOR, "hint_color", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_INSTANCE_INDEX, "instance_index", CF_UNSPECIFIED, {}, {} },
// sampler hints
- { TK_HINT_ALBEDO_TEXTURE, "hint_albedo", CF_UNSPECIFIED, {}, {} },
- { TK_HINT_BLACK_ALBEDO_TEXTURE, "hint_black_albedo", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_NORMAL_TEXTURE, "hint_normal", CF_UNSPECIFIED, {}, {} },
- { TK_HINT_WHITE_TEXTURE, "hint_white", CF_UNSPECIFIED, {}, {} },
- { TK_HINT_BLACK_TEXTURE, "hint_black", CF_UNSPECIFIED, {}, {} },
+ { TK_HINT_DEFAULT_WHITE_TEXTURE, "hint_default_white", CF_UNSPECIFIED, {}, {} },
+ { TK_HINT_DEFAULT_BLACK_TEXTURE, "hint_default_black", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_ANISOTROPY_TEXTURE, "hint_anisotropy", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_ROUGHNESS_R, "hint_roughness_r", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_ROUGHNESS_G, "hint_roughness_g", CF_UNSPECIFIED, {}, {} },
@@ -617,12 +613,16 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
String str;
int i = 0;
+ bool digit_after_exp = false;
while (true) {
const char32_t symbol = String::char_lowercase(GETCHAR(i));
bool error = false;
if (is_digit(symbol)) {
+ if (exponent_found) {
+ digit_after_exp = true;
+ }
if (end_suffix_found) {
error = true;
}
@@ -687,7 +687,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant");
}
} else if (period_found || exponent_found || float_suffix_found) { // Float
- if (exponent_found && (!is_digit(last_char) && last_char != 'f')) { // checks for eg: "2E", "2E-", "2E+"
+ if (exponent_found && (!digit_after_exp || (!is_digit(last_char) && last_char != 'f'))) { // Checks for eg: "2E", "2E-", "2E+" and 0ef, 0e+f, 0.0ef, 0.0e-f (exponent without digit after it).
return _make_token(TK_ERROR, "Invalid (float) numeric constant");
}
if (period_found) {
@@ -1018,6 +1018,93 @@ String ShaderLanguage::get_datatype_name(DataType p_type) {
return "";
}
+String ShaderLanguage::get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint) {
+ String result;
+ switch (p_hint) {
+ case ShaderNode::Uniform::HINT_RANGE: {
+ result = "hint_range";
+ } break;
+ case ShaderNode::Uniform::HINT_SOURCE_COLOR: {
+ result = "hint_color";
+ } break;
+ case ShaderNode::Uniform::HINT_NORMAL: {
+ result = "hint_normal";
+ } break;
+ case ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL: {
+ result = "hint_roughness_normal";
+ } break;
+ case ShaderNode::Uniform::HINT_ROUGHNESS_R: {
+ result = "hint_roughness_r";
+ } break;
+ case ShaderNode::Uniform::HINT_ROUGHNESS_G: {
+ result = "hint_roughness_g";
+ } break;
+ case ShaderNode::Uniform::HINT_ROUGHNESS_B: {
+ result = "hint_roughness_b";
+ } break;
+ case ShaderNode::Uniform::HINT_ROUGHNESS_A: {
+ result = "hint_roughness_a";
+ } break;
+ case ShaderNode::Uniform::HINT_ROUGHNESS_GRAY: {
+ result = "hint_roughness_gray";
+ } break;
+ case ShaderNode::Uniform::HINT_DEFAULT_BLACK: {
+ result = "hint_default_black";
+ } break;
+ case ShaderNode::Uniform::HINT_DEFAULT_WHITE: {
+ result = "hint_default_white";
+ } break;
+ case ShaderNode::Uniform::HINT_ANISOTROPY: {
+ result = "hint_anisotropy";
+ } break;
+ default:
+ break;
+ }
+ return result;
+}
+
+String ShaderLanguage::get_texture_filter_name(TextureFilter p_filter) {
+ String result;
+ switch (p_filter) {
+ case FILTER_NEAREST: {
+ result = "filter_nearest";
+ } break;
+ case FILTER_LINEAR: {
+ result = "filter_linear";
+ } break;
+ case FILTER_NEAREST_MIPMAP: {
+ result = "filter_nearest_mipmap";
+ } break;
+ case FILTER_LINEAR_MIPMAP: {
+ result = "filter_linear_mipmap";
+ } break;
+ case FILTER_NEAREST_MIPMAP_ANISOTROPIC: {
+ result = "filter_nearest_mipmap_anisotropic";
+ } break;
+ case FILTER_LINEAR_MIPMAP_ANISOTROPIC: {
+ result = "filter_linear_mipmap_anisotropic";
+ } break;
+ default: {
+ } break;
+ }
+ return result;
+}
+
+String ShaderLanguage::get_texture_repeat_name(TextureRepeat p_repeat) {
+ String result;
+ switch (p_repeat) {
+ case REPEAT_DISABLE: {
+ result = "repeat_disable";
+ } break;
+ case REPEAT_ENABLE: {
+ result = "repeat_enable";
+ } break;
+ default: {
+ } break;
+ }
+ return result;
+}
+
bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) {
return is_token_datatype(p_type) && p_type != TK_TYPE_VOID;
}
@@ -1771,21 +1858,21 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "ivec4", TYPE_IVEC4, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
@@ -1799,22 +1886,22 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "int", TYPE_INT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "int", TYPE_INT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "int", TYPE_INT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "int", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "float", TYPE_FLOAT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "float", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bool", TYPE_BOOL, { TYPE_INT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bool", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
// Conversion vectors.
@@ -1826,57 +1913,57 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "vec2", TYPE_VEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec2", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec2", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec2", TYPE_BVEC2, { TYPE_IVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec2", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "ivec3", TYPE_IVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "ivec3", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "ivec3", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec3", TYPE_VEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec3", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec3", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec3", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec3", TYPE_BVEC3, { TYPE_IVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec3", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "ivec4", TYPE_IVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "ivec4", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "ivec4", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec4", TYPE_VEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec4", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "vec4", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
- { "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
+ { "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec4", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec4", TYPE_BVEC4, { TYPE_IVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
- { "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, true },
+ { "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
{ "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, { "" }, TAG_GLOBAL, false },
// Conversion between matrixes.
@@ -2120,10 +2207,10 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
// modf
- { "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, true },
- { "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, true },
- { "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, true },
- { "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, true },
+ { "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
+ { "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
+ { "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
+ { "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, { "x", "i" }, TAG_GLOBAL, false },
// min
@@ -2143,13 +2230,13 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
// max
@@ -2169,13 +2256,13 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
// clamp
@@ -2195,13 +2282,13 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
{ "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
- { "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, true },
- { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, true },
- { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, true },
- { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, true },
- { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, true },
- { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, true },
- { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, true },
+ { "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
+ { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID }, { "x", "minVal", "maxVal" }, TAG_GLOBAL, false },
// mix
@@ -2252,31 +2339,31 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
// floatBitsToInt
- { "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
+ { "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
// floatBitsToUint
- { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
+ { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
// intBitsToFloat
- { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
+ { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
// uintBitsToFloat
- { "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
- { "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, true },
+ { "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
+ { "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, { "x" }, TAG_GLOBAL, false },
// Built-ins - geometric functions.
// length
@@ -2365,9 +2452,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "lessThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "lessThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
// greaterThan
@@ -2379,9 +2466,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "greaterThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "greaterThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
// lessThanEqual
@@ -2393,9 +2480,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "lessThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "lessThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
// greaterThanEqual
@@ -2407,9 +2494,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "greaterThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "greaterThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
// equal
@@ -2421,9 +2508,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "equal", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "equal", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "equal", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "equal", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
@@ -2439,9 +2526,9 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "notEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "notEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
- { "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
- { "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, true },
+ { "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
+ { "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "notEqual", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
{ "notEqual", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, { "a", "b" }, TAG_GLOBAL, false },
@@ -2468,38 +2555,38 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
// Built-ins: texture functions.
// textureSize
- { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
- { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBEARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBEARRAY, TYPE_INT, TYPE_VOID }, { "sampler", "lod" }, TAG_GLOBAL, false },
// texture
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
@@ -2507,119 +2594,119 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
// textureProj
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, true },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "bias" }, TAG_GLOBAL, false },
// textureLod
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
- { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
+ { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
// texelFetch
- { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
+ { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
// textureProjLod
- { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
- { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, true },
+ { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
+ { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, { "sampler", "coords", "lod" }, TAG_GLOBAL, false },
// textureGrad
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
- { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords", "dPdx", "dPdy" }, TAG_GLOBAL, false },
// textureGather
- { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, true },
- { "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, true },
+ { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, { "sampler", "coords" }, TAG_GLOBAL, false },
+ { "textureGather", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_INT, TYPE_VOID }, { "sampler", "coords", "comp" }, TAG_GLOBAL, false },
// dFdx
- { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
// dFdy
- { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
// fwidth
- { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
- { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true },
+ { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
+ { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false },
// Sub-functions.
// array
- { "length", TYPE_INT, { TYPE_VOID }, { "" }, TAG_ARRAY, true },
+ { "length", TYPE_INT, { TYPE_VOID }, { "" }, TAG_ARRAY, false },
// Modern functions.
// fma
@@ -2631,17 +2718,17 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
// Packing/Unpacking functions.
- { "packHalf2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "packUnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "packSnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "packUnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "packSnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
+ { "packHalf2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "packUnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "packSnorm2x16", TYPE_UINT, { TYPE_VEC2, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "packUnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "packSnorm4x8", TYPE_UINT, { TYPE_VEC4, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
- { "unpackHalf2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "unpackUnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "unpackSnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "unpackUnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
- { "unpackSnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, true },
+ { "unpackHalf2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "unpackUnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "unpackSnorm2x16", TYPE_VEC2, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "unpackUnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
+ { "unpackSnorm4x8", TYPE_VEC4, { TYPE_UINT, TYPE_VOID }, { "v" }, TAG_GLOBAL, false },
// bitfieldExtract
@@ -3421,17 +3508,7 @@ bool ShaderLanguage::is_float_type(DataType p_type) {
}
}
bool ShaderLanguage::is_sampler_type(DataType p_type) {
- return p_type == TYPE_SAMPLER2D ||
- p_type == TYPE_ISAMPLER2D ||
- p_type == TYPE_USAMPLER2D ||
- p_type == TYPE_SAMPLER2DARRAY ||
- p_type == TYPE_ISAMPLER2DARRAY ||
- p_type == TYPE_USAMPLER2DARRAY ||
- p_type == TYPE_SAMPLER3D ||
- p_type == TYPE_ISAMPLER3D ||
- p_type == TYPE_USAMPLER3D ||
- p_type == TYPE_SAMPLERCUBE ||
- p_type == TYPE_SAMPLERCUBEARRAY;
+ return p_type > TYPE_MAT4 && p_type < TYPE_STRUCT;
}
Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
@@ -3618,7 +3695,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 3;
- if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
PackedColorArray array = PackedColorArray();
for (int i = 0; i < array_size; i += 3) {
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
@@ -3632,7 +3709,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
value = Variant(array);
}
} else {
- if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real));
} else {
value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
@@ -3643,7 +3720,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
if (array_size > 0) {
array_size *= 4;
- if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
PackedColorArray array = PackedColorArray();
for (int i = 0; i < array_size; i += 4) {
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
@@ -3660,7 +3737,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
value = Variant(array);
}
} else {
- if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
} else {
value = Variant(Quaternion(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
@@ -3842,14 +3919,14 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
break;
case ShaderLanguage::TYPE_VEC3:
if (p_uniform.array_size > 0) {
- if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
pi.type = Variant::PACKED_COLOR_ARRAY;
} else {
pi.type = Variant::PACKED_VECTOR3_ARRAY;
}
} else {
- if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
pi.type = Variant::COLOR;
} else {
@@ -3859,13 +3936,13 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
break;
case ShaderLanguage::TYPE_VEC4: {
if (p_uniform.array_size > 0) {
- if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
pi.type = Variant::PACKED_COLOR_ARRAY;
} else {
pi.type = Variant::PACKED_FLOAT32_ARRAY;
}
} else {
- if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+ if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
pi.type = Variant::COLOR;
} else {
pi.type = Variant::QUATERNION;
@@ -4019,7 +4096,7 @@ uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) {
}
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
- RBSet<String> kws;
+ HashSet<String> kws;
int idx = 0;
@@ -4036,8 +4113,8 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
idx++;
}
- for (RBSet<String>::Element *E = kws.front(); E; E = E->next()) {
- r_keywords->push_back(E->get());
+ for (const String &E : kws) {
+ r_keywords->push_back(E);
}
}
@@ -4056,7 +4133,7 @@ bool ShaderLanguage::is_control_flow_keyword(String p_keyword) {
}
void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) {
- RBSet<String> kws;
+ HashSet<String> kws;
int idx = 0;
@@ -4066,8 +4143,8 @@ void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) {
idx++;
}
- for (RBSet<String>::Element *E = kws.front(); E; E = E->next()) {
- r_keywords->push_back(E->get());
+ for (const String &E : kws) {
+ r_keywords->push_back(E);
}
}
@@ -4340,9 +4417,9 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam
arg->tex_argument_check = true;
arg->tex_argument_filter = p_filter;
arg->tex_argument_repeat = p_repeat;
- for (KeyValue<StringName, RBSet<int>> &E : arg->tex_argument_connect) {
- for (RBSet<int>::Element *F = E.value.front(); F; F = F->next()) {
- if (!_propagate_function_call_sampler_uniform_settings(E.key, F->get(), p_filter, p_repeat)) {
+ for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) {
+ for (const int &F : E.value) {
+ if (!_propagate_function_call_sampler_uniform_settings(E.key, F, p_filter, p_repeat)) {
return false;
}
}
@@ -4374,9 +4451,9 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
arg->tex_builtin_check = true;
arg->tex_builtin = p_builtin;
- for (KeyValue<StringName, RBSet<int>> &E : arg->tex_argument_connect) {
- for (RBSet<int>::Element *F = E.value.front(); F; F = F->next()) {
- if (!_propagate_function_call_sampler_builtin_reference(E.key, F->get(), p_builtin)) {
+ for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) {
+ for (const int &F : E.value) {
+ if (!_propagate_function_call_sampler_builtin_reference(E.key, F, p_builtin)) {
return false;
}
}
@@ -5096,7 +5173,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
for (int j = 0; j < base_function->arguments.size(); j++) {
if (base_function->arguments[j].name == varname) {
if (!base_function->arguments[j].tex_argument_connect.has(call_function->name)) {
- base_function->arguments.write[j].tex_argument_connect[call_function->name] = RBSet<int>();
+ base_function->arguments.write[j].tex_argument_connect[call_function->name] = HashSet<int>();
}
base_function->arguments.write[j].tex_argument_connect[call_function->name].insert(i);
found = true;
@@ -5379,6 +5456,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_CURSOR) {
//do nothing
} else if (tk.type == TK_PERIOD) {
+#ifdef DEBUG_ENABLED
+ uint32_t prev_keyword_completion_context = keyword_completion_context;
+ keyword_completion_context = CF_UNSPECIFIED;
+#endif
+
DataType dt = expr->get_datatype();
String st = expr->get_datatype_name();
@@ -5734,6 +5816,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
expr = mn;
+#ifdef DEBUG_ENABLED
+ keyword_completion_context = prev_keyword_completion_context;
+#endif
+
//todo
//member (period) has priority over any operator
//creates a subindexing expression in place
@@ -6567,10 +6653,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
DataType type = is_struct ? TYPE_STRUCT : get_token_datatype(tk.type);
- if (_validate_datatype(type) != OK) {
- return ERR_PARSE_ERROR;
- }
-
if (precision != PRECISION_DEFAULT && _validate_precision(type, precision) != OK) {
return ERR_PARSE_ERROR;
}
@@ -6667,11 +6749,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- if (RenderingServer::get_singleton()->is_low_end() && is_const) {
- _set_error(RTR("Local const arrays are only supported on high-end platforms."));
- return ERR_PARSE_ERROR;
- }
-
Error error = _parse_array_size(p_block, p_function_info, false, &decl.size_expression, &var.array_size, &unknown_size);
if (error != OK) {
return error;
@@ -6691,11 +6768,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
bool full_def = false;
if (tk.type == TK_OP_ASSIGN) {
- if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error(RTR("Array initialization is only supported on high-end platforms."));
- return ERR_PARSE_ERROR;
- }
-
TkPos prev_pos = _get_tkpos();
tk = _get_token();
@@ -7002,11 +7074,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
_set_tkpos(pos); //rollback
}
} else if (tk.type == TK_CF_SWITCH) {
- if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error(vformat(RTR("The '%s' operator is only supported on high-end platforms."), "switch"));
- return ERR_PARSE_ERROR;
- }
-
// switch() {}
tk = _get_token();
if (tk.type != TK_PARENTHESIS_OPEN) {
@@ -7062,7 +7129,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
_set_tkpos(pos);
continue;
} else {
- RBSet<int> constants;
+ HashSet<int> constants;
for (int i = 0; i < switch_block->statements.size(); i++) { // Checks for duplicates.
ControlFlowNode *flow = static_cast<ControlFlowNode *>(switch_block->statements[i]);
if (flow) {
@@ -7565,15 +7632,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
return OK;
}
-String ShaderLanguage::_get_shader_type_list(const RBSet<String> &p_shader_types) const {
+String ShaderLanguage::_get_shader_type_list(const HashSet<String> &p_shader_types) const {
// Return a list of shader types as an human-readable string
String valid_types;
- for (const RBSet<String>::Element *E = p_shader_types.front(); E; E = E->next()) {
+ for (const String &E : p_shader_types) {
if (!valid_types.is_empty()) {
valid_types += ", ";
}
- valid_types += "'" + E->get() + "'";
+ valid_types += "'" + E + "'";
}
return valid_types;
@@ -7610,36 +7677,7 @@ Error ShaderLanguage::_validate_precision(DataType p_type, DataPrecision p_preci
return OK;
}
-Error ShaderLanguage::_validate_datatype(DataType p_type) {
- if (RenderingServer::get_singleton()->is_low_end()) {
- bool invalid_type = false;
-
- switch (p_type) {
- case TYPE_UINT:
- case TYPE_UVEC2:
- case TYPE_UVEC3:
- case TYPE_UVEC4:
- case TYPE_ISAMPLER2D:
- case TYPE_USAMPLER2D:
- case TYPE_ISAMPLER3D:
- case TYPE_USAMPLER3D:
- case TYPE_USAMPLER2DARRAY:
- case TYPE_ISAMPLER2DARRAY:
- invalid_type = true;
- break;
- default:
- break;
- }
-
- if (invalid_type) {
- _set_error(vformat(RTR("The \"%s\" type is only supported on high-end platforms."), get_datatype_name(p_type)));
- return ERR_UNAVAILABLE;
- }
- }
- return OK;
-}
-
-Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const RBSet<String> &p_shader_types) {
+Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const HashSet<String> &p_shader_types) {
Token tk = _get_token();
TkPos prev_pos;
Token next;
@@ -7790,7 +7828,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
st.shader_struct = st_node;
int member_count = 0;
- RBSet<String> member_names;
+ HashSet<String> member_names;
while (true) { // variables list
#ifdef DEBUG_ENABLED
@@ -7975,11 +8013,11 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
[[fallthrough]];
case TK_UNIFORM:
case TK_VARYING: {
- bool uniform = tk.type == TK_UNIFORM;
+ bool is_uniform = tk.type == TK_UNIFORM;
#ifdef DEBUG_ENABLED
keyword_completion_context = CF_UNSPECIFIED;
#endif // DEBUG_ENABLED
- if (!uniform) {
+ if (!is_uniform) {
if (shader_type_identifier == "particles" || shader_type_identifier == "sky" || shader_type_identifier == "fog") {
_set_error(vformat(RTR("Varyings cannot be used in '%s' shaders."), shader_type_identifier));
return ERR_PARSE_ERROR;
@@ -7996,7 +8034,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
bool temp_error = false;
uint32_t datatype_flag;
- if (!uniform) {
+ if (!is_uniform) {
datatype_flag = CF_VARYING_TYPE;
keyword_completion_context = CF_INTERPOLATION_QUALIFIER | CF_PRECISION_MODIFIER | datatype_flag;
@@ -8024,7 +8062,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
#endif // DEBUG_ENABLED
if (is_token_interpolation(tk.type)) {
- if (uniform) {
+ if (is_uniform) {
_set_error(RTR("Interpolation qualifiers are not supported for uniforms."));
#ifdef DEBUG_ENABLED
temp_error = true;
@@ -8070,7 +8108,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
}
if (shader->structs.has(tk.text)) {
- if (uniform) {
+ if (is_uniform) {
_set_error(vformat(RTR("The '%s' data type is not supported for uniforms."), "struct"));
return ERR_PARSE_ERROR;
} else {
@@ -8095,7 +8133,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
return ERR_PARSE_ERROR;
}
- if (!uniform && (type < TYPE_FLOAT || type > TYPE_MAT4)) {
+ if (!is_uniform && (type < TYPE_FLOAT || type > TYPE_MAT4)) {
_set_error(RTR("Invalid type for varying, only 'float', 'vec2', 'vec3', 'vec4', 'mat2', 'mat3', 'mat4', or arrays of these types are allowed."));
return ERR_PARSE_ERROR;
}
@@ -8136,7 +8174,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
return ERR_PARSE_ERROR;
}
- if (uniform) {
+ if (is_uniform) {
if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL && Engine::get_singleton()->is_editor_hint()) { // Type checking for global uniforms is not allowed outside the editor.
//validate global uniform
DataType gvtype = global_var_get_type_func(name);
@@ -8150,16 +8188,16 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
return ERR_PARSE_ERROR;
}
}
- ShaderNode::Uniform uniform2;
+ ShaderNode::Uniform uniform;
- uniform2.type = type;
- uniform2.scope = uniform_scope;
- uniform2.precision = precision;
- uniform2.array_size = array_size;
+ uniform.type = type;
+ uniform.scope = uniform_scope;
+ uniform.precision = precision;
+ uniform.array_size = array_size;
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_array_size(nullptr, constants, true, nullptr, &uniform2.array_size, nullptr);
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &uniform.array_size, nullptr);
if (error != OK) {
return error;
}
@@ -8171,36 +8209,33 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
_set_error(vformat(RTR("The '%s' qualifier is not supported for sampler types."), "SCOPE_INSTANCE"));
return ERR_PARSE_ERROR;
}
- uniform2.texture_order = texture_uniforms++;
- uniform2.texture_binding = texture_binding;
- if (uniform2.array_size > 0) {
- texture_binding += uniform2.array_size;
+ uniform.texture_order = texture_uniforms++;
+ uniform.texture_binding = texture_binding;
+ if (uniform.array_size > 0) {
+ texture_binding += uniform.array_size;
} else {
++texture_binding;
}
- uniform2.order = -1;
- if (_validate_datatype(type) != OK) {
- return ERR_PARSE_ERROR;
- }
+ uniform.order = -1;
} else {
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
_set_error(vformat(RTR("The '%s' qualifier is not supported for matrix types."), "SCOPE_INSTANCE"));
return ERR_PARSE_ERROR;
}
- uniform2.texture_order = -1;
+ uniform.texture_order = -1;
if (uniform_scope != ShaderNode::Uniform::SCOPE_INSTANCE) {
- uniform2.order = uniforms++;
+ uniform.order = uniforms++;
#ifdef DEBUG_ENABLED
if (check_device_limit_warnings) {
- if (uniform2.array_size > 0) {
- int size = get_datatype_size(uniform2.type) * uniform2.array_size;
- int m = (16 * uniform2.array_size);
+ if (uniform.array_size > 0) {
+ int size = get_datatype_size(uniform.type) * uniform.array_size;
+ int m = (16 * uniform.array_size);
if ((size % m) != 0U) {
size += m - (size % m);
}
uniform_buffer_size += size;
} else {
- uniform_buffer_size += get_datatype_size(uniform2.type);
+ uniform_buffer_size += get_datatype_size(uniform.type);
}
if (uniform_buffer_exceeded_line == -1 && uniform_buffer_size > max_uniform_buffer_size) {
@@ -8211,7 +8246,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
}
}
- if (uniform2.array_size > 0) {
+ if (uniform.array_size > 0) {
if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
_set_error(vformat(RTR("The '%s' qualifier is not supported for uniform arrays."), "SCOPE_GLOBAL"));
return ERR_PARSE_ERROR;
@@ -8227,7 +8262,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
if (tk.type == TK_COLON) {
completion_type = COMPLETION_HINT;
completion_base = type;
- completion_base_array = uniform2.array_size > 0;
+ completion_base_array = uniform.array_size > 0;
//hint
do {
@@ -8239,179 +8274,251 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
return ERR_PARSE_ERROR;
}
- if (uniform2.array_size > 0) {
- if (tk.type != TK_HINT_COLOR) {
+ if (uniform.array_size > 0) {
+ if (tk.type != TK_HINT_SOURCE_COLOR) {
_set_error(RTR("This hint is not supported for uniform arrays."));
return ERR_PARSE_ERROR;
}
}
- if (tk.type == TK_HINT_WHITE_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_WHITE;
- } else if (tk.type == TK_HINT_BLACK_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_BLACK;
- } else if (tk.type == TK_HINT_NORMAL_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_NORMAL;
- } else if (tk.type == TK_HINT_ROUGHNESS_NORMAL_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL;
- } else if (tk.type == TK_HINT_ROUGHNESS_R) {
- uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_R;
- } else if (tk.type == TK_HINT_ROUGHNESS_G) {
- uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_G;
- } else if (tk.type == TK_HINT_ROUGHNESS_B) {
- uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_B;
- } else if (tk.type == TK_HINT_ROUGHNESS_A) {
- uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_A;
- } else if (tk.type == TK_HINT_ROUGHNESS_GRAY) {
- uniform2.hint = ShaderNode::Uniform::HINT_ROUGHNESS_GRAY;
- } else if (tk.type == TK_HINT_ANISOTROPY_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_ANISOTROPY;
- } else if (tk.type == TK_HINT_ALBEDO_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_ALBEDO;
- } else if (tk.type == TK_HINT_BLACK_ALBEDO_TEXTURE) {
- uniform2.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO;
- } else if (tk.type == TK_HINT_COLOR) {
- if (type != TYPE_VEC3 && type != TYPE_VEC4) {
- _set_error(vformat(RTR("Color hint is for '%s' or '%s' only."), "vec3", "vec4"));
- return ERR_PARSE_ERROR;
- }
- uniform2.hint = ShaderNode::Uniform::HINT_COLOR;
- } else if (tk.type == TK_HINT_RANGE) {
- uniform2.hint = ShaderNode::Uniform::HINT_RANGE;
- if (type != TYPE_FLOAT && type != TYPE_INT) {
- _set_error(vformat(RTR("Range hint is for '%s' and '%s' only."), "float", "int"));
- return ERR_PARSE_ERROR;
- }
-
- tk = _get_token();
- if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_expected_after_error("(", "hint_range");
- return ERR_PARSE_ERROR;
- }
+ ShaderNode::Uniform::Hint new_hint = ShaderNode::Uniform::HINT_NONE;
+ TextureFilter new_filter = FILTER_DEFAULT;
+ TextureRepeat new_repeat = REPEAT_DEFAULT;
- tk = _get_token();
+ switch (tk.type) {
+ case TK_HINT_SOURCE_COLOR: {
+ if (type != TYPE_VEC3 && type != TYPE_VEC4 && !is_sampler_type(type)) {
+ _set_error(vformat(RTR("Source color hint is for '%s', '%s' or sampler types only."), "vec3", "vec4"));
+ return ERR_PARSE_ERROR;
+ }
- float sign = 1.0;
+ if (is_sampler_type(type)) {
+ if (uniform.use_color) {
+ _set_error(vformat(RTR("Duplicated hint: '%s'."), "source_color"));
+ return ERR_PARSE_ERROR;
+ }
+ uniform.use_color = true;
+ } else {
+ new_hint = ShaderNode::Uniform::HINT_SOURCE_COLOR;
+ }
+ } break;
+ case TK_HINT_DEFAULT_BLACK_TEXTURE: {
+ new_hint = ShaderNode::Uniform::HINT_DEFAULT_BLACK;
+ } break;
+ case TK_HINT_DEFAULT_WHITE_TEXTURE: {
+ new_hint = ShaderNode::Uniform::HINT_DEFAULT_WHITE;
+ } break;
+ case TK_HINT_NORMAL_TEXTURE: {
+ new_hint = ShaderNode::Uniform::HINT_NORMAL;
+ } break;
+ case TK_HINT_ROUGHNESS_NORMAL_TEXTURE: {
+ new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_NORMAL;
+ } break;
+ case TK_HINT_ROUGHNESS_R: {
+ new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_R;
+ } break;
+ case TK_HINT_ROUGHNESS_G: {
+ new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_G;
+ } break;
+ case TK_HINT_ROUGHNESS_B: {
+ new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_B;
+ } break;
+ case TK_HINT_ROUGHNESS_A: {
+ new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_A;
+ } break;
+ case TK_HINT_ROUGHNESS_GRAY: {
+ new_hint = ShaderNode::Uniform::HINT_ROUGHNESS_GRAY;
+ } break;
+ case TK_HINT_ANISOTROPY_TEXTURE: {
+ new_hint = ShaderNode::Uniform::HINT_ANISOTROPY;
+ } break;
+ case TK_HINT_RANGE: {
+ if (type != TYPE_FLOAT && type != TYPE_INT) {
+ _set_error(vformat(RTR("Range hint is for '%s' and '%s' only."), "float", "int"));
+ return ERR_PARSE_ERROR;
+ }
- if (tk.type == TK_OP_SUB) {
- sign = -1.0;
tk = _get_token();
- }
-
- if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
- _set_error(RTR("Expected an integer constant."));
- return ERR_PARSE_ERROR;
- }
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_expected_after_error("(", "hint_range");
+ return ERR_PARSE_ERROR;
+ }
- uniform2.hint_range[0] = tk.constant;
- uniform2.hint_range[0] *= sign;
+ tk = _get_token();
- tk = _get_token();
+ float sign = 1.0;
- if (tk.type != TK_COMMA) {
- _set_error(RTR("Expected ',' after integer constant."));
- return ERR_PARSE_ERROR;
- }
+ if (tk.type == TK_OP_SUB) {
+ sign = -1.0;
+ tk = _get_token();
+ }
- tk = _get_token();
+ if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
+ _set_error(RTR("Expected an integer constant."));
+ return ERR_PARSE_ERROR;
+ }
- sign = 1.0;
+ uniform.hint_range[0] = tk.constant;
+ uniform.hint_range[0] *= sign;
- if (tk.type == TK_OP_SUB) {
- sign = -1.0;
tk = _get_token();
- }
- if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
- _set_error(RTR("Expected an integer constant after ','."));
- return ERR_PARSE_ERROR;
- }
+ if (tk.type != TK_COMMA) {
+ _set_error(RTR("Expected ',' after integer constant."));
+ return ERR_PARSE_ERROR;
+ }
- uniform2.hint_range[1] = tk.constant;
- uniform2.hint_range[1] *= sign;
+ tk = _get_token();
- tk = _get_token();
+ sign = 1.0;
- if (tk.type == TK_COMMA) {
- tk = _get_token();
+ if (tk.type == TK_OP_SUB) {
+ sign = -1.0;
+ tk = _get_token();
+ }
if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
_set_error(RTR("Expected an integer constant after ','."));
return ERR_PARSE_ERROR;
}
- uniform2.hint_range[2] = tk.constant;
+ uniform.hint_range[1] = tk.constant;
+ uniform.hint_range[1] *= sign;
+
tk = _get_token();
- } else {
- if (type == TYPE_INT) {
- uniform2.hint_range[2] = 1;
+
+ if (tk.type == TK_COMMA) {
+ tk = _get_token();
+
+ if (tk.type != TK_FLOAT_CONSTANT && !tk.is_integer_constant()) {
+ _set_error(RTR("Expected an integer constant after ','."));
+ return ERR_PARSE_ERROR;
+ }
+
+ uniform.hint_range[2] = tk.constant;
+ tk = _get_token();
} else {
- uniform2.hint_range[2] = 0.001;
+ if (type == TYPE_INT) {
+ uniform.hint_range[2] = 1;
+ } else {
+ uniform.hint_range[2] = 0.001;
+ }
}
- }
- if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_expected_error(")");
- return ERR_PARSE_ERROR;
- }
- } else if (tk.type == TK_HINT_INSTANCE_INDEX) {
- if (custom_instance_index != -1) {
- _set_error(vformat(RTR("Can only specify '%s' once."), "instance_index"));
- return ERR_PARSE_ERROR;
- }
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_expected_error(")");
+ return ERR_PARSE_ERROR;
+ }
- tk = _get_token();
- if (tk.type != TK_PARENTHESIS_OPEN) {
- _set_expected_after_error("(", "instance_index");
- return ERR_PARSE_ERROR;
- }
+ new_hint = ShaderNode::Uniform::HINT_RANGE;
+ } break;
+ case TK_HINT_INSTANCE_INDEX: {
+ if (custom_instance_index != -1) {
+ _set_error(vformat(RTR("Can only specify '%s' once."), "instance_index"));
+ return ERR_PARSE_ERROR;
+ }
- tk = _get_token();
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_expected_after_error("(", "instance_index");
+ return ERR_PARSE_ERROR;
+ }
- if (tk.type == TK_OP_SUB) {
- _set_error(RTR("The instance index can't be negative."));
- return ERR_PARSE_ERROR;
- }
+ tk = _get_token();
- if (!tk.is_integer_constant()) {
- _set_error(RTR("Expected an integer constant."));
- return ERR_PARSE_ERROR;
- }
+ if (tk.type == TK_OP_SUB) {
+ _set_error(RTR("The instance index can't be negative."));
+ return ERR_PARSE_ERROR;
+ }
+
+ if (!tk.is_integer_constant()) {
+ _set_error(RTR("Expected an integer constant."));
+ return ERR_PARSE_ERROR;
+ }
+
+ custom_instance_index = tk.constant;
- custom_instance_index = tk.constant;
+ if (custom_instance_index >= MAX_INSTANCE_UNIFORM_INDICES) {
+ _set_error(vformat(RTR("Allowed instance uniform indices must be within [0..%d] range."), MAX_INSTANCE_UNIFORM_INDICES - 1));
+ return ERR_PARSE_ERROR;
+ }
+
+ tk = _get_token();
+
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_expected_error(")");
+ return ERR_PARSE_ERROR;
+ }
+ } break;
+ case TK_FILTER_NEAREST: {
+ new_filter = FILTER_NEAREST;
+ } break;
+ case TK_FILTER_LINEAR: {
+ new_filter = FILTER_LINEAR;
+ } break;
+ case TK_FILTER_NEAREST_MIPMAP: {
+ new_filter = FILTER_NEAREST_MIPMAP;
+ } break;
+ case TK_FILTER_LINEAR_MIPMAP: {
+ new_filter = FILTER_LINEAR_MIPMAP;
+ } break;
+ case TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC: {
+ new_filter = FILTER_NEAREST_MIPMAP_ANISOTROPIC;
+ } break;
+ case TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC: {
+ new_filter = FILTER_LINEAR_MIPMAP_ANISOTROPIC;
+ } break;
+ case TK_REPEAT_DISABLE: {
+ new_repeat = REPEAT_DISABLE;
+ } break;
+ case TK_REPEAT_ENABLE: {
+ new_repeat = REPEAT_ENABLE;
+ } break;
+ default:
+ break;
+ }
+ if (((new_filter != FILTER_DEFAULT || new_repeat != REPEAT_DEFAULT) || (new_hint != ShaderNode::Uniform::HINT_NONE && new_hint != ShaderNode::Uniform::HINT_SOURCE_COLOR && new_hint != ShaderNode::Uniform::HINT_RANGE)) && !is_sampler_type(type)) {
+ _set_error(RTR("This hint is only for sampler types."));
+ return ERR_PARSE_ERROR;
+ }
- if (custom_instance_index >= MAX_INSTANCE_UNIFORM_INDICES) {
- _set_error(vformat(RTR("Allowed instance uniform indices must be within [0..%d] range."), MAX_INSTANCE_UNIFORM_INDICES - 1));
+ if (new_hint != ShaderNode::Uniform::HINT_NONE) {
+ if (uniform.hint != ShaderNode::Uniform::HINT_NONE) {
+ if (uniform.hint == new_hint) {
+ _set_error(vformat(RTR("Duplicated hint: '%s'."), get_uniform_hint_name(new_hint)));
+ } else {
+ _set_error(vformat(RTR("Redefinition of hint: '%s'. The hint has already been set to '%s'."), get_uniform_hint_name(new_hint), get_uniform_hint_name(uniform.hint)));
+ }
return ERR_PARSE_ERROR;
+ } else {
+ uniform.hint = new_hint;
}
+ }
- tk = _get_token();
-
- if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_expected_error(")");
+ if (new_filter != FILTER_DEFAULT) {
+ if (uniform.filter != FILTER_DEFAULT) {
+ if (uniform.filter == new_filter) {
+ _set_error(vformat(RTR("Duplicated hint: '%s'."), get_texture_filter_name(new_filter)));
+ } else {
+ _set_error(vformat(RTR("Redefinition of hint: '%s'. The filter mode has already been set to '%s'."), get_texture_filter_name(new_filter), get_texture_filter_name(uniform.filter)));
+ }
return ERR_PARSE_ERROR;
+ } else {
+ uniform.filter = new_filter;
}
- } else if (tk.type == TK_FILTER_LINEAR) {
- uniform2.filter = FILTER_LINEAR;
- } else if (tk.type == TK_FILTER_NEAREST) {
- uniform2.filter = FILTER_NEAREST;
- } else if (tk.type == TK_FILTER_NEAREST_MIPMAP) {
- uniform2.filter = FILTER_NEAREST_MIPMAP;
- } else if (tk.type == TK_FILTER_LINEAR_MIPMAP) {
- uniform2.filter = FILTER_LINEAR_MIPMAP;
- } else if (tk.type == TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC) {
- uniform2.filter = FILTER_NEAREST_MIPMAP_ANISOTROPIC;
- } else if (tk.type == TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC) {
- uniform2.filter = FILTER_LINEAR_MIPMAP_ANISOTROPIC;
- } else if (tk.type == TK_REPEAT_DISABLE) {
- uniform2.repeat = REPEAT_DISABLE;
- } else if (tk.type == TK_REPEAT_ENABLE) {
- uniform2.repeat = REPEAT_ENABLE;
}
- if (uniform2.hint != ShaderNode::Uniform::HINT_RANGE && uniform2.hint != ShaderNode::Uniform::HINT_NONE && uniform2.hint != ShaderNode::Uniform::HINT_COLOR && type <= TYPE_MAT4) {
- _set_error(RTR("This hint is only for sampler types."));
- return ERR_PARSE_ERROR;
+ if (new_repeat != REPEAT_DEFAULT) {
+ if (uniform.repeat != REPEAT_DEFAULT) {
+ if (uniform.repeat == new_repeat) {
+ _set_error(vformat(RTR("Duplicated hint: '%s'."), get_texture_repeat_name(new_repeat)));
+ } else {
+ _set_error(vformat(RTR("Redefinition of hint: '%s'. The repeat mode has already been set to '%s'."), get_texture_repeat_name(new_repeat), get_texture_repeat_name(uniform.repeat)));
+ }
+ return ERR_PARSE_ERROR;
+ } else {
+ uniform.repeat = new_repeat;
+ }
}
tk = _get_token();
@@ -8421,9 +8528,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE) {
if (custom_instance_index >= 0) {
- uniform2.instance_index = custom_instance_index;
+ uniform.instance_index = custom_instance_index;
} else {
- uniform2.instance_index = instance_index++;
+ uniform.instance_index = instance_index++;
if (instance_index > MAX_INSTANCE_UNIFORM_INDICES) {
_set_error(vformat(RTR("Too many '%s' uniforms in shader, maximum supported is %d."), "instance", MAX_INSTANCE_UNIFORM_INDICES));
return ERR_PARSE_ERROR;
@@ -8434,7 +8541,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
//reset scope for next uniform
if (tk.type == TK_OP_ASSIGN) {
- if (uniform2.array_size > 0) {
+ if (uniform.array_size > 0) {
_set_error(RTR("Setting default values to uniform arrays is not supported."));
return ERR_PARSE_ERROR;
}
@@ -8450,16 +8557,16 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
ConstantNode *cn = static_cast<ConstantNode *>(expr);
- uniform2.default_value.resize(cn->values.size());
+ uniform.default_value.resize(cn->values.size());
- if (!convert_constant(cn, uniform2.type, uniform2.default_value.ptrw())) {
- _set_error(vformat(RTR("Can't convert constant to '%s'."), get_datatype_name(uniform2.type)));
+ if (!convert_constant(cn, uniform.type, uniform.default_value.ptrw())) {
+ _set_error(vformat(RTR("Can't convert constant to '%s'."), get_datatype_name(uniform.type)));
return ERR_PARSE_ERROR;
}
tk = _get_token();
}
- shader->uniforms[name] = uniform2;
+ shader->uniforms[name] = uniform;
#ifdef DEBUG_ENABLED
if (check_warnings && HAS_WARNING(ShaderWarning::UNUSED_UNIFORM_FLAG)) {
used_uniforms.insert(name, Usage(tk_line));
@@ -8585,10 +8692,6 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
bool fixed_array_size = false;
if (tk.type == TK_BRACKET_OPEN) {
- if (is_constant && RenderingServer::get_singleton()->is_low_end()) {
- _set_error(RTR("Global constant arrays are only supported on high-end platforms."));
- return ERR_PARSE_ERROR;
- }
Error error = _parse_array_size(nullptr, constants, !is_constant, nullptr, &array_size, &unknown_size);
if (error != OK) {
return error;
@@ -8633,10 +8736,6 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
constant.array_size = array_size;
if (tk.type == TK_BRACKET_OPEN) {
- if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error(RTR("Global const arrays are only supported on high-end platforms."));
- return ERR_PARSE_ERROR;
- }
Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size);
if (error != OK) {
return error;
@@ -9104,9 +9203,6 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
param_type = TYPE_STRUCT;
} else {
param_type = get_token_datatype(tk.type);
- if (_validate_datatype(param_type) != OK) {
- return ERR_PARSE_ERROR;
- }
if (param_type == TYPE_VOID) {
_set_error(RTR("Void type not allowed as argument."));
return ERR_PARSE_ERROR;
@@ -9793,7 +9889,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
}
int idx2 = 0;
- RBSet<int> out_args;
+ HashSet<int> out_args;
while (builtin_func_out_args[idx2].name != nullptr) {
if (builtin_func_out_args[idx2].name == builtin_func_defs[idx].name) {
for (int i = 0; i < BuiltinFuncOutArgs::MAX_ARGS; i++) {
@@ -9913,7 +10009,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
} break;
case COMPLETION_HINT: {
if (completion_base == DataType::TYPE_VEC3 || completion_base == DataType::TYPE_VEC4) {
- ScriptLanguage::CodeCompletionOption option("hint_color", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
+ ScriptLanguage::CodeCompletionOption option("source_color", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
r_options->push_back(option);
} else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) {
ScriptLanguage::CodeCompletionOption option("hint_range", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
@@ -9935,10 +10031,9 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
options.push_back("filter_nearest");
options.push_back("filter_nearest_mipmap");
options.push_back("filter_nearest_mipmap_anisotropic");
- options.push_back("hint_albedo");
options.push_back("hint_anisotropy");
- options.push_back("hint_black");
- options.push_back("hint_black_albedo");
+ options.push_back("hint_default_black");
+ options.push_back("hint_default_white");
options.push_back("hint_normal");
options.push_back("hint_roughness_a");
options.push_back("hint_roughness_b");
@@ -9946,7 +10041,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
options.push_back("hint_roughness_gray");
options.push_back("hint_roughness_normal");
options.push_back("hint_roughness_r");
- options.push_back("hint_white");
+ options.push_back("source_color");
options.push_back("repeat_enable");
options.push_back("repeat_disable");
}
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index d4a2e0b549..2b147fbeb1 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -160,8 +160,8 @@ public:
TK_ARG_OUT,
TK_ARG_INOUT,
TK_RENDER_MODE,
- TK_HINT_WHITE_TEXTURE,
- TK_HINT_BLACK_TEXTURE,
+ TK_HINT_DEFAULT_WHITE_TEXTURE,
+ TK_HINT_DEFAULT_BLACK_TEXTURE,
TK_HINT_NORMAL_TEXTURE,
TK_HINT_ROUGHNESS_NORMAL_TEXTURE,
TK_HINT_ROUGHNESS_R,
@@ -170,9 +170,7 @@ public:
TK_HINT_ROUGHNESS_A,
TK_HINT_ROUGHNESS_GRAY,
TK_HINT_ANISOTROPY_TEXTURE,
- TK_HINT_ALBEDO_TEXTURE,
- TK_HINT_BLACK_ALBEDO_TEXTURE,
- TK_HINT_COLOR,
+ TK_HINT_SOURCE_COLOR,
TK_HINT_RANGE,
TK_HINT_INSTANCE_INDEX,
TK_FILTER_NEAREST,
@@ -503,7 +501,7 @@ public:
BlockNode *parent_block = nullptr;
enum BlockType {
- BLOCK_TYPE_STANDART,
+ BLOCK_TYPE_STANDARD,
BLOCK_TYPE_FOR_INIT,
BLOCK_TYPE_FOR_CONDITION,
BLOCK_TYPE_FOR_EXPRESSION,
@@ -512,7 +510,7 @@ public:
BLOCK_TYPE_DEFAULT,
};
- int block_type = BLOCK_TYPE_STANDART;
+ int block_type = BLOCK_TYPE_STANDARD;
SubClassTag block_tag = SubClassTag::TAG_GLOBAL;
struct Variable {
@@ -589,7 +587,7 @@ public:
bool is_const;
int array_size;
- HashMap<StringName, RBSet<int>> tex_argument_connect;
+ HashMap<StringName, HashSet<int>> tex_argument_connect;
};
StringName name;
@@ -622,7 +620,7 @@ public:
struct Function {
StringName name;
FunctionNode *function = nullptr;
- RBSet<StringName> uses_function;
+ HashSet<StringName> uses_function;
bool callable;
};
@@ -653,10 +651,8 @@ public:
struct Uniform {
enum Hint {
HINT_NONE,
- HINT_COLOR,
HINT_RANGE,
- HINT_ALBEDO,
- HINT_BLACK_ALBEDO,
+ HINT_SOURCE_COLOR,
HINT_NORMAL,
HINT_ROUGHNESS_NORMAL,
HINT_ROUGHNESS_R,
@@ -664,8 +660,8 @@ public:
HINT_ROUGHNESS_B,
HINT_ROUGHNESS_A,
HINT_ROUGHNESS_GRAY,
- HINT_BLACK,
- HINT_WHITE,
+ HINT_DEFAULT_BLACK,
+ HINT_DEFAULT_WHITE,
HINT_ANISOTROPY,
HINT_MAX
};
@@ -685,6 +681,7 @@ public:
Vector<ConstantNode::Value> default_value;
Scope scope = SCOPE_LOCAL;
Hint hint = HINT_NONE;
+ bool use_color = false;
TextureFilter filter = FILTER_DEFAULT;
TextureRepeat repeat = REPEAT_DEFAULT;
float hint_range[3];
@@ -760,6 +757,9 @@ public:
static DataPrecision get_token_precision(TokenType p_type);
static String get_precision_name(DataPrecision p_type);
static String get_datatype_name(DataType p_type);
+ static String get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint);
+ static String get_texture_filter_name(TextureFilter p_filter);
+ static String get_texture_repeat_name(TextureRepeat p_repeat);
static bool is_token_nonvoid_datatype(TokenType p_type);
static bool is_token_operator(TokenType p_type);
static bool is_token_operator_assign(TokenType p_type);
@@ -1049,7 +1049,6 @@ private:
static bool is_const_suffix_lut_initialized;
Error _validate_precision(DataType p_type, DataPrecision p_precision);
- Error _validate_datatype(DataType p_type);
bool _compare_datatypes(DataType p_datatype_a, String p_datatype_name_a, int p_array_size_a, DataType p_datatype_b, String p_datatype_name_b, int p_array_size_b);
bool _compare_datatypes_in_nodes(Node *a, Node *b);
@@ -1068,10 +1067,10 @@ private:
Node *_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
Error _parse_block(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false);
- String _get_shader_type_list(const RBSet<String> &p_shader_types) const;
+ String _get_shader_type_list(const HashSet<String> &p_shader_types) const;
String _get_qualifier_str(ArgumentQualifier p_qualifier) const;
- Error _parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const RBSet<String> &p_shader_types);
+ Error _parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const HashSet<String> &p_shader_types);
Error _find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op);
Error _find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op);
@@ -1097,7 +1096,7 @@ public:
HashMap<StringName, FunctionInfo> functions;
Vector<ModeInfo> render_modes;
VaryingFunctionNames varying_function_names = VaryingFunctionNames();
- RBSet<String> shader_types;
+ HashSet<String> shader_types;
GlobalVariableGetTypeFunc global_variable_type_func = nullptr;
};
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 98c7f0d7aa..5772179d68 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -39,7 +39,7 @@ const Vector<ShaderLanguage::ModeInfo> &ShaderTypes::get_modes(RS::ShaderMode p_
return shader_modes[p_mode].modes;
}
-const RBSet<String> &ShaderTypes::get_types() const {
+const HashSet<String> &ShaderTypes::get_types() const {
return shader_types;
}
@@ -192,26 +192,26 @@ ShaderTypes::ShaderTypes() {
// spatial render modes
{
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "blend", "mix", "add", "sub", "mul" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_draw", "opaque", "always", "never" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_prepass_alpha" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_test_disabled" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "sss_mode_skin" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "cull", "back", "front", "disabled" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "unshaded" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "wireframe" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "diffuse", "lambert", "lambert_wrap", "burley", "toon" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "specular", "schlick_ggx", "toon", "disabled" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "skip_vertex_transform" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "world_vertex_coords" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "ensure_correct_normals" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "shadows_disabled" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "ambient_light_disabled" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "shadow_to_opacity" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "vertex_lighting" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "particle_trails" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "alpha_to_coverage" });
- shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "alpha_to_coverage_and_one" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("blend"), "mix", "add", "sub", "mul" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("depth_draw"), "opaque", "always", "never" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("depth_prepass_alpha") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("depth_test_disabled") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("sss_mode_skin") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("cull"), "back", "front", "disabled" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("unshaded") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("wireframe") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("diffuse"), "lambert", "lambert_wrap", "burley", "toon" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("specular"), "schlick_ggx", "toon", "disabled" });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("skip_vertex_transform") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("world_vertex_coords") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("ensure_correct_normals") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("shadows_disabled") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("ambient_light_disabled") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("shadow_to_opacity") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("vertex_lighting") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("particle_trails") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage") });
+ shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage_and_one") });
}
/************ CANVAS ITEM **************************/
@@ -299,10 +299,10 @@ ShaderTypes::ShaderTypes() {
// canvasitem render modes
{
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "skip_vertex_transform" });
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "blend", "mix", "add", "sub", "mul", "premul_alpha", "disabled" });
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "unshaded" });
- shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "light_only" });
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("skip_vertex_transform") });
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("blend"), "mix", "add", "sub", "mul", "premul_alpha", "disabled" });
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("unshaded") });
+ shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("light_only") });
}
/************ PARTICLES **************************/
@@ -380,10 +380,10 @@ ShaderTypes::ShaderTypes() {
// particles render modes
{
- shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "collision_use_scale" });
- shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "disable_force" });
- shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "disable_velocity" });
- shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "keep_data" });
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("collision_use_scale") });
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("disable_force") });
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("disable_velocity") });
+ shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("keep_data") });
}
/************ SKY **************************/
@@ -422,6 +422,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["EYEDIR"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["SCREEN_UV"] = constt(ShaderLanguage::TYPE_VEC2);
+ shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["FRAGCOORD"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["SKY_COORDS"] = constt(ShaderLanguage::TYPE_VEC2);
shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["HALF_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[RS::SHADER_SKY].functions["sky"].built_ins["QUARTER_RES_COLOR"] = constt(ShaderLanguage::TYPE_VEC4);
@@ -430,9 +431,9 @@ ShaderTypes::ShaderTypes() {
// sky render modes
{
- shader_modes[RS::SHADER_SKY].modes.push_back({ "use_half_res_pass" });
- shader_modes[RS::SHADER_SKY].modes.push_back({ "use_quarter_res_pass" });
- shader_modes[RS::SHADER_SKY].modes.push_back({ "disable_fog" });
+ shader_modes[RS::SHADER_SKY].modes.push_back({ PNAME("use_half_res_pass") });
+ shader_modes[RS::SHADER_SKY].modes.push_back({ PNAME("use_quarter_res_pass") });
+ shader_modes[RS::SHADER_SKY].modes.push_back({ PNAME("disable_fog") });
}
/************ FOG **************************/
diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h
index e0fee0a822..107525cd15 100644
--- a/servers/rendering/shader_types.h
+++ b/servers/rendering/shader_types.h
@@ -45,7 +45,7 @@ class ShaderTypes {
static ShaderTypes *singleton;
- RBSet<String> shader_types;
+ HashSet<String> shader_types;
List<String> shader_types_list;
public:
@@ -53,7 +53,7 @@ public:
const HashMap<StringName, ShaderLanguage::FunctionInfo> &get_functions(RS::ShaderMode p_mode) const;
const Vector<ShaderLanguage::ModeInfo> &get_modes(RS::ShaderMode p_mode) const;
- const RBSet<String> &get_types() const;
+ const HashSet<String> &get_types() const;
const List<String> &get_types_list() const;
ShaderTypes();
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index 4c4213d7c1..e3a969d032 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -111,12 +111,6 @@ public:
/* RENDER TARGET */
- enum RenderTargetFlags {
- RENDER_TARGET_TRANSPARENT,
- RENDER_TARGET_DIRECT_TO_SCREEN,
- RENDER_TARGET_FLAG_MAX
- };
-
virtual RID render_target_create() = 0;
virtual void render_target_free(RID p_rid) = 0;
@@ -124,7 +118,8 @@ public:
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) = 0;
virtual RID render_target_get_texture(RID p_render_target) = 0;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
- virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
+ virtual void render_target_set_transparent(RID p_render_target, bool p_is_transparent) = 0;
+ virtual void render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) = 0;
virtual bool render_target_was_used(RID p_render_target) = 0;
virtual void render_target_set_as_unused(RID p_render_target) = 0;
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 766ca88e34..26ab8b659e 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -2140,8 +2140,11 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("fog_volume_set_material", "fog_volume", "material"), &RenderingServer::fog_volume_set_material);
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_ELLIPSOID);
+ BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_CONE);
+ BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_CYLINDER);
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_BOX);
BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_WORLD);
+ BIND_ENUM_CONSTANT(FOG_VOLUME_SHAPE_MAX);
/* VISIBILITY NOTIFIER */
@@ -2208,6 +2211,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision);
ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa);
ClassDB::bind_method(D_METHOD("viewport_set_screen_space_aa", "viewport", "mode"), &RenderingServer::viewport_set_screen_space_aa);
+ ClassDB::bind_method(D_METHOD("viewport_set_use_taa", "viewport", "enable"), &RenderingServer::viewport_set_use_taa);
ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "enable"), &RenderingServer::viewport_set_use_debanding);
ClassDB::bind_method(D_METHOD("viewport_set_use_occlusion_culling", "viewport", "enable"), &RenderingServer::viewport_set_use_occlusion_culling);
ClassDB::bind_method(D_METHOD("viewport_set_occlusion_rays_per_thread", "rays_per_thread"), &RenderingServer::viewport_set_occlusion_rays_per_thread);
@@ -2294,6 +2298,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_OCCLUDERS);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_MOTION_VECTORS);
/* SKY API */
@@ -2818,7 +2823,9 @@ RenderingServer::RenderingServer() {
thread_pool = memnew(RendererThreadPool);
singleton = this;
+}
+void RenderingServer::init() {
GLOBAL_DEF_RST("rendering/textures/vram_compression/import_bptc", false);
GLOBAL_DEF_RST("rendering/textures/vram_compression/import_s3tc", true);
GLOBAL_DEF_RST("rendering/textures/vram_compression/import_etc", false);
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index d622571a47..39484e532a 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -724,8 +724,11 @@ public:
enum FogVolumeShape {
FOG_VOLUME_SHAPE_ELLIPSOID,
+ FOG_VOLUME_SHAPE_CONE,
+ FOG_VOLUME_SHAPE_CYLINDER,
FOG_VOLUME_SHAPE_BOX,
FOG_VOLUME_SHAPE_WORLD,
+ FOG_VOLUME_SHAPE_MAX,
};
virtual void fog_volume_set_shape(RID p_fog_volume, FogVolumeShape p_shape) = 0;
@@ -874,11 +877,13 @@ public:
virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0;
+ virtual void viewport_set_use_taa(RID p_viewport, bool p_use_taa) = 0;
+
virtual void viewport_set_use_debanding(RID p_viewport, bool p_use_debanding) = 0;
virtual void viewport_set_mesh_lod_threshold(RID p_viewport, float p_pixels) = 0;
- virtual void viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_debanding) = 0;
+ virtual void viewport_set_use_occlusion_culling(RID p_viewport, bool p_use_occlusion_culling) = 0;
virtual void viewport_set_occlusion_rays_per_thread(int p_rays_per_thread) = 0;
enum ViewportOcclusionCullingBuildQuality {
@@ -930,6 +935,7 @@ public:
VIEWPORT_DEBUG_DRAW_CLUSTER_DECALS,
VIEWPORT_DEBUG_DRAW_CLUSTER_REFLECTION_PROBES,
VIEWPORT_DEBUG_DRAW_OCCLUDERS,
+ VIEWPORT_DEBUG_DRAW_MOTION_VECTORS,
};
virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
@@ -1468,7 +1474,7 @@ public:
virtual void draw(bool p_swap_buffers = true, double frame_step = 0.0) = 0;
virtual void sync() = 0;
virtual bool has_changed() const = 0;
- virtual void init() = 0;
+ virtual void init();
virtual void finish() = 0;
/* STATUS INFORMATION */
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index 005cb68302..e9a558ac5f 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -55,6 +55,11 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(font_set_data, "font_rid", "data");
GDVIRTUAL_BIND(font_set_data_ptr, "font_rid", "data_ptr", "data_size");
+ GDVIRTUAL_BIND(font_set_face_index, "font_rid", "face_index");
+ GDVIRTUAL_BIND(font_get_face_index, "font_rid");
+
+ GDVIRTUAL_BIND(font_get_face_count, "font_rid");
+
GDVIRTUAL_BIND(font_set_style, "font_rid", "style");
GDVIRTUAL_BIND(font_get_style, "font_rid");
@@ -413,6 +418,26 @@ void TextServerExtension::font_set_data_ptr(const RID &p_font_rid, const uint8_t
GDVIRTUAL_CALL(font_set_data_ptr, p_font_rid, p_data_ptr, p_data_size);
}
+void TextServerExtension::font_set_face_index(const RID &p_font_rid, int64_t p_index) {
+ GDVIRTUAL_CALL(font_set_face_index, p_font_rid, p_index);
+}
+
+int64_t TextServerExtension::font_get_face_index(const RID &p_font_rid) const {
+ int64_t ret;
+ if (GDVIRTUAL_CALL(font_get_face_index, p_font_rid, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+int64_t TextServerExtension::font_get_face_count(const RID &p_font_rid) const {
+ int64_t ret;
+ if (GDVIRTUAL_CALL(font_get_face_count, p_font_rid, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
void TextServerExtension::font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) {
GDVIRTUAL_CALL(font_set_style, p_font_rid, p_style);
}
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 7b7fc61ed7..9ca0939247 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -84,6 +84,14 @@ public:
GDVIRTUAL2(font_set_data, RID, const PackedByteArray &);
GDVIRTUAL3(font_set_data_ptr, RID, GDNativeConstPtr<const uint8_t>, int64_t);
+ virtual void font_set_face_index(const RID &p_font_rid, int64_t p_index) override;
+ virtual int64_t font_get_face_index(const RID &p_font_rid) const override;
+ GDVIRTUAL2(font_set_face_index, RID, int64_t);
+ GDVIRTUAL1RC(int64_t, font_get_face_index, RID);
+
+ virtual int64_t font_get_face_count(const RID &p_font_rid) const override;
+ GDVIRTUAL1RC(int64_t, font_get_face_count, RID);
+
virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) override;
virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const override;
GDVIRTUAL2(font_set_style, RID, int64_t);
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 7d9945f5d7..41d9c74d82 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -75,7 +75,7 @@ void TextServerManager::remove_interface(const Ref<TextServer> &p_interface) {
};
};
- ERR_FAIL_COND(idx == -1);
+ ERR_FAIL_COND_MSG(idx == -1, "Interface not found.");
print_verbose("TextServer: Removed interface \"" + p_interface->get_name() + "\"");
emit_signal(SNAME("interface_removed"), p_interface->get_name());
interfaces.remove_at(idx);
@@ -99,7 +99,7 @@ Ref<TextServer> TextServerManager::find_interface(const String &p_name) const {
};
};
- ERR_FAIL_COND_V(idx == -1, nullptr);
+ ERR_FAIL_COND_V_MSG(idx == -1, nullptr, "Interface not found.");
return interfaces[idx];
}
@@ -208,6 +208,11 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_set_data", "font_rid", "data"), &TextServer::font_set_data);
+ ClassDB::bind_method(D_METHOD("font_set_face_index", "font_rid", "face_index"), &TextServer::font_set_face_index);
+ ClassDB::bind_method(D_METHOD("font_get_face_index", "font_rid"), &TextServer::font_get_face_index);
+
+ ClassDB::bind_method(D_METHOD("font_get_face_count", "font_rid"), &TextServer::font_get_face_count);
+
ClassDB::bind_method(D_METHOD("font_set_style", "font_rid", "style"), &TextServer::font_set_style);
ClassDB::bind_method(D_METHOD("font_get_style", "font_rid"), &TextServer::font_get_style);
diff --git a/servers/text_server.h b/servers/text_server.h
index f96146a549..a67ad8fc9e 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -189,6 +189,11 @@ public:
virtual void font_set_data(const RID &p_font_rid, const PackedByteArray &p_data) = 0;
virtual void font_set_data_ptr(const RID &p_font_rid, const uint8_t *p_data_ptr, int64_t p_data_size) = 0;
+ virtual void font_set_face_index(const RID &p_font_rid, int64_t p_index) = 0;
+ virtual int64_t font_get_face_index(const RID &p_font_rid) const = 0;
+
+ virtual int64_t font_get_face_count(const RID &p_font_rid) const = 0;
+
virtual void font_set_style(const RID &p_font_rid, int64_t /*FontStyle*/ p_style) = 0;
virtual int64_t /*FontStyle*/ font_get_style(const RID &p_font_rid) const = 0;
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index 8314e356d2..ad61aa94bc 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -184,7 +184,7 @@ void XRServer::remove_interface(const Ref<XRInterface> &p_interface) {
};
};
- ERR_FAIL_COND(idx == -1);
+ ERR_FAIL_COND_MSG(idx == -1, "Interface not found.");
print_verbose("XR: Removed interface" + p_interface->get_name());
@@ -211,7 +211,7 @@ Ref<XRInterface> XRServer::find_interface(const String &p_name) const {
};
};
- ERR_FAIL_COND_V(idx == -1, nullptr);
+ ERR_FAIL_COND_V_MSG(idx == -1, nullptr, "Interface not found.");
return interfaces[idx];
};