diff options
24 files changed, 199 insertions, 88 deletions
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index 090ca5a033..585b94a522 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -1085,8 +1085,8 @@ <member name="TranslationServer" type="TranslationServer" setter="" getter=""> The [TranslationServer] singleton. </member> - <member name="VisualScriptEditor" type="VisualScriptEditor" setter="" getter=""> - The [VisualScriptEditor] singleton. + <member name="VisualScriptEditor" type="VisualScriptCustomNodes" setter="" getter=""> + The [VisualScriptCustomNodes] singleton. </member> <member name="XRServer" type="XRServer" setter="" getter=""> The [XRServer] singleton. diff --git a/doc/classes/GradientTexture.xml b/doc/classes/GradientTexture.xml index 242a78b2e4..44da042dd4 100644 --- a/doc/classes/GradientTexture.xml +++ b/doc/classes/GradientTexture.xml @@ -14,6 +14,9 @@ <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient"> The [Gradient] that will be used to fill the texture. </member> + <member name="use_hdr" type="bool" setter="set_use_hdr" getter="is_using_hdr" default="false"> + If [code]true[/code], the generated texture will support high dynamic range ([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/code], the generated texture will use low dynamic range; overbright colors will be clamped ([constant Image.FORMAT_RGBA8] format). + </member> <member name="width" type="int" setter="set_width" getter="get_width" default="2048"> The number of color samples that will be obtained from the [Gradient]. </member> diff --git a/modules/visual_script/doc_classes/VisualScriptEditor.xml b/doc/classes/VisualScriptCustomNodes.xml index 9ea889c77b..3ef8022f5e 100644 --- a/modules/visual_script/doc_classes/VisualScriptEditor.xml +++ b/doc/classes/VisualScriptCustomNodes.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="VisualScriptEditor" inherits="Object" version="4.0"> +<class name="VisualScriptCustomNodes" inherits="Object" version="4.0"> <brief_description> + Manages custom nodes for the Visual Script editor. </brief_description> <description> + This singleton can be used to manage (i.e., add or remove) custom nodes for the Visual Script editor. </description> <tutorials> </tutorials> diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index c4f67ffa5a..830b010d01 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1738,6 +1738,8 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay onion.capture.shader = Ref<Shader>(memnew(Shader)); onion.capture.shader->set_code(R"( +// Animation editor onion skinning shader. + shader_type canvas_item; uniform vec4 bkg_color; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index d3821f2f81..291cafab2b 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -5598,6 +5598,8 @@ void Node3DEditor::_init_indicators() { Ref<Shader> grid_shader = memnew(Shader); grid_shader->set_code(R"( +// 3D editor grid shader. + shader_type spatial; render_mode unshaded; @@ -5839,6 +5841,8 @@ void fragment() { Ref<Shader> rotate_shader = memnew(Shader); rotate_shader->set_code(R"( +// 3D editor rotation manipulator gizmo shader. + shader_type spatial; render_mode unshaded, depth_test_disabled; @@ -5887,6 +5891,8 @@ void fragment() { Ref<Shader> border_shader = memnew(Shader); border_shader->set_code(R"( +// 3D editor rotation manipulator gizmo shader (white outline). + shader_type spatial; render_mode unshaded, depth_test_disabled; @@ -7506,6 +7512,8 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { sun_direction_shader.instantiate(); sun_direction_shader->set_code(R"( +// 3D editor Preview Sun direction shader. + shader_type canvas_item; uniform vec3 sun_direction; diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp index 3bdf97647a..bd1923f4ab 100644 --- a/editor/plugins/texture_3d_editor_plugin.cpp +++ b/editor/plugins/texture_3d_editor_plugin.cpp @@ -76,6 +76,8 @@ void Texture3DEditor::_update_material() { void Texture3DEditor::_make_shaders() { shader.instantiate(); shader->set_code(R"( +// Texture3DEditor preview shader. + shader_type canvas_item; uniform sampler3D tex; diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp index 4180eb73d9..424e018a47 100644 --- a/editor/plugins/texture_layered_editor_plugin.cpp +++ b/editor/plugins/texture_layered_editor_plugin.cpp @@ -106,6 +106,8 @@ void TextureLayeredEditor::_update_material() { void TextureLayeredEditor::_make_shaders() { shaders[0].instantiate(); shaders[0]->set_code(R"( +// TextureLayeredEditor preview shader (2D array). + shader_type canvas_item; uniform sampler2DArray tex; @@ -118,6 +120,8 @@ void fragment() { shaders[1].instantiate(); shaders[1]->set_code(R"( +// TextureLayeredEditor preview shader (cubemap). + shader_type canvas_item; uniform samplerCube tex; @@ -132,6 +136,8 @@ void fragment() { shaders[2].instantiate(); shaders[2]->set_code(R"( +// TextureLayeredEditor preview shader (cubemap array). + shader_type canvas_item; uniform samplerCubeArray tex; diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp index fce98eb8a0..7fb9707fce 100644 --- a/modules/visual_script/register_types.cpp +++ b/modules/visual_script/register_types.cpp @@ -43,7 +43,7 @@ VisualScriptLanguage *visual_script_language = nullptr; #ifdef TOOLS_ENABLED -static vs_bind::VisualScriptEditor *vs_editor_singleton = nullptr; +static VisualScriptCustomNodes *vs_custom_nodes_singleton = nullptr; #endif void register_visual_script_types() { @@ -114,10 +114,10 @@ void register_visual_script_types() { #ifdef TOOLS_ENABLED ClassDB::set_current_api(ClassDB::API_EDITOR); - GDREGISTER_CLASS(vs_bind::VisualScriptEditor); + GDREGISTER_CLASS(VisualScriptCustomNodes); ClassDB::set_current_api(ClassDB::API_CORE); - vs_editor_singleton = memnew(vs_bind::VisualScriptEditor); - Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", vs_bind::VisualScriptEditor::get_singleton())); + vs_custom_nodes_singleton = memnew(VisualScriptCustomNodes); + Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", VisualScriptCustomNodes::get_singleton())); VisualScriptEditor::register_editor(); #endif @@ -130,8 +130,8 @@ void unregister_visual_script_types() { #ifdef TOOLS_ENABLED VisualScriptEditor::free_clipboard(); - if (vs_editor_singleton) { - memdelete(vs_editor_singleton); + if (vs_custom_nodes_singleton) { + memdelete(vs_custom_nodes_singleton); } #endif if (visual_script_language) { diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index ded716cf18..eee9e8f32b 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -4522,46 +4522,44 @@ void VisualScriptEditor::register_editor() { void VisualScriptEditor::validate() { } -namespace vs_bind { +// VisualScriptCustomNodes -Ref<VisualScriptNode> VisualScriptEditor::create_node_custom(const String &p_name) { +Ref<VisualScriptNode> VisualScriptCustomNodes::create_node_custom(const String &p_name) { Ref<VisualScriptCustomNode> node; node.instantiate(); node->set_script(singleton->custom_nodes[p_name]); return node; } -VisualScriptEditor *VisualScriptEditor::singleton = nullptr; -Map<String, REF> VisualScriptEditor::custom_nodes; +VisualScriptCustomNodes *VisualScriptCustomNodes::singleton = nullptr; +Map<String, REF> VisualScriptCustomNodes::custom_nodes; -VisualScriptEditor::VisualScriptEditor() { +VisualScriptCustomNodes::VisualScriptCustomNodes() { singleton = this; } -VisualScriptEditor::~VisualScriptEditor() { +VisualScriptCustomNodes::~VisualScriptCustomNodes() { custom_nodes.clear(); } -void VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { +void VisualScriptCustomNodes::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) { String node_name = "custom/" + p_category + "/" + p_name; custom_nodes.insert(node_name, p_script); - VisualScriptLanguage::singleton->add_register_func(node_name, &VisualScriptEditor::create_node_custom); + VisualScriptLanguage::singleton->add_register_func(node_name, &VisualScriptCustomNodes::create_node_custom); emit_signal(SNAME("custom_nodes_updated")); } -void VisualScriptEditor::remove_custom_node(const String &p_name, const String &p_category) { +void VisualScriptCustomNodes::remove_custom_node(const String &p_name, const String &p_category) { String node_name = "custom/" + p_category + "/" + p_name; custom_nodes.erase(node_name); VisualScriptLanguage::singleton->remove_register_func(node_name); emit_signal(SNAME("custom_nodes_updated")); } -void VisualScriptEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &VisualScriptEditor::add_custom_node); - ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &VisualScriptEditor::remove_custom_node); +void VisualScriptCustomNodes::_bind_methods() { + ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &VisualScriptCustomNodes::add_custom_node); + ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &VisualScriptCustomNodes::remove_custom_node); ADD_SIGNAL(MethodInfo("custom_nodes_updated")); } -} // namespace vs_bind - #endif diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h index 4fa8ffca67..7dfb4fa270 100644 --- a/modules/visual_script/visual_script_editor.h +++ b/modules/visual_script/visual_script_editor.h @@ -46,6 +46,8 @@ class VisualScriptEditorVariableEdit; // TODO: Maybe this class should be refactored. // See https://github.com/godotengine/godot/issues/51913 class VisualScriptEditor : public ScriptEditorBase { + GDCLASS(VisualScriptEditor, ScriptEditorBase); + enum { TYPE_SEQUENCE = 1000, INDEX_BASE_SEQUENCE = 1024 @@ -330,33 +332,29 @@ public: ~VisualScriptEditor(); }; -namespace vs_bind { - // Singleton -class VisualScriptEditor : public Object { - GDCLASS(VisualScriptEditor, Object); +class VisualScriptCustomNodes : public Object { + GDCLASS(VisualScriptCustomNodes, Object); friend class VisualScriptLanguage; protected: static void _bind_methods(); - static VisualScriptEditor *singleton; + static VisualScriptCustomNodes *singleton; static Map<String, REF> custom_nodes; static Ref<VisualScriptNode> create_node_custom(const String &p_name); public: - static VisualScriptEditor *get_singleton() { return singleton; } + static VisualScriptCustomNodes *get_singleton() { return singleton; } void add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script); void remove_custom_node(const String &p_name, const String &p_category); - VisualScriptEditor(); - ~VisualScriptEditor(); + VisualScriptCustomNodes(); + ~VisualScriptCustomNodes(); }; -} // namespace vs_bind - #endif #endif // VISUALSCRIPT_EDITOR_H diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp index ea0222cb19..0e98af71fa 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.cpp +++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp @@ -32,6 +32,8 @@ #include "core/config/project_settings.h" #include "core/os/os.h" +#include "core/version.h" +#include "core/version_hash.gen.h" #include "main/main.h" #ifdef DEBUG_ENABLED @@ -61,12 +63,19 @@ static void handle_crash(int sig) { } // Dump the backtrace to stderr with a message to the user + fprintf(stderr, "\n================================================================\n"); fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig); if (OS::get_singleton()->get_main_loop()) { OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH); } + // Print the engine version just before, so that people are reminded to include the version in backtrace reports. + if (String(VERSION_HASH).length() != 0) { + fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n"); + } else { + fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n"); + } fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data()); char **strings = backtrace_symbols(bt_buffer, size); if (strings) { @@ -115,6 +124,7 @@ static void handle_crash(int sig) { free(strings); } fprintf(stderr, "-- END OF BACKTRACE --\n"); + fprintf(stderr, "================================================================\n"); // Abort to pass the error to the OS abort(); diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index 0f128d504f..31228b10b4 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -32,6 +32,8 @@ #include "core/config/project_settings.h" #include "core/os/os.h" +#include "core/version.h" +#include "core/version_hash.gen.h" #include "main/main.h" #include <string.h> @@ -85,11 +87,18 @@ static void handle_crash(int sig) { } // Dump the backtrace to stderr with a message to the user + fprintf(stderr, "\n================================================================\n"); fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig); if (OS::get_singleton()->get_main_loop()) OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH); + // Print the engine version just before, so that people are reminded to include the version in backtrace reports. + if (String(VERSION_HASH).length() != 0) { + fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n"); + } else { + fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n"); + } fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data()); char **strings = backtrace_symbols(bt_buffer, size); if (strings) { @@ -148,6 +157,7 @@ static void handle_crash(int sig) { free(strings); } fprintf(stderr, "-- END OF BACKTRACE --\n"); + fprintf(stderr, "================================================================\n"); // Abort to pass the error to the OS abort(); diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp index e2d507eddd..1b4dae207f 100644 --- a/platform/windows/crash_handler_windows.cpp +++ b/platform/windows/crash_handler_windows.cpp @@ -32,6 +32,8 @@ #include "core/config/project_settings.h" #include "core/os/os.h" +#include "core/version.h" +#include "core/version_hash.gen.h" #include "main/main.h" #ifdef CRASH_HANDLER_EXCEPTION @@ -127,6 +129,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) { return EXCEPTION_CONTINUE_SEARCH; } + fprintf(stderr, "\n================================================================\n"); fprintf(stderr, "%s: Program crashed\n", __FUNCTION__); if (OS::get_singleton()->get_main_loop()) @@ -175,6 +178,12 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) { msg = proj_settings->get("debug/settings/crash_handler/message"); } + // Print the engine version just before, so that people are reminded to include the version in backtrace reports. + if (String(VERSION_HASH).length() != 0) { + fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n"); + } else { + fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n"); + } fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data()); int n = 0; @@ -200,6 +209,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) { } while (frame.AddrReturn.Offset != 0 && n < 256); fprintf(stderr, "-- END OF BACKTRACE --\n"); + fprintf(stderr, "================================================================\n"); SymCleanup(process); diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp index 4c36618c99..d34331e1d8 100644 --- a/scene/3d/physics_body_3d.cpp +++ b/scene/3d/physics_body_3d.cpp @@ -1080,8 +1080,6 @@ void RigidBody3D::_reload_physics_characteristics() { #define FLOOR_ANGLE_THRESHOLD 0.01 bool CharacterBody3D::move_and_slide() { - Vector3 body_velocity_normal = linear_velocity.normalized(); - bool was_on_floor = on_floor; // Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky @@ -1111,7 +1109,7 @@ bool CharacterBody3D::move_and_slide() { floor_normal = Vector3(); floor_velocity = Vector3(); - if (current_floor_velocity != Vector3() && on_floor_body.is_valid()) { + if (!current_floor_velocity.is_equal_approx(Vector3()) && on_floor_body.is_valid()) { PhysicsServer3D::MotionResult floor_result; Set<RID> exclude; exclude.insert(on_floor_body); @@ -1130,39 +1128,35 @@ bool CharacterBody3D::move_and_slide() { for (int iteration = 0; iteration < max_slides; ++iteration) { PhysicsServer3D::MotionResult result; - bool found_collision = false; - bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled); - if (!collided) { - motion = Vector3(); //clear because no collision happened and motion completed - } else { - found_collision = true; - + if (collided) { motion_results.push_back(result); _set_collision_direction(result); - if (on_floor && floor_stop_on_slope) { - if ((body_velocity_normal + up_direction).length() < 0.01) { - Transform3D gt = get_global_transform(); - if (result.travel.length() > margin) { - gt.origin -= result.travel.slide(up_direction); - } else { - gt.origin -= result.travel; - } - set_global_transform(gt); - linear_velocity = Vector3(); - return true; + if (on_floor && floor_stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) { + Transform3D gt = get_global_transform(); + if (result.travel.length() > margin) { + gt.origin -= result.travel.slide(up_direction); + } else { + gt.origin -= result.travel; } + set_global_transform(gt); + linear_velocity = Vector3(); + motion = Vector3(); + break; } - if (sliding_enabled || !on_floor) { - motion = result.remainder.slide(result.collision_normal); - linear_velocity = linear_velocity.slide(result.collision_normal); + if (result.remainder.is_equal_approx(Vector3())) { + motion = Vector3(); + break; + } - for (int j = 0; j < 3; j++) { - if (locked_axis & (1 << j)) { - linear_velocity[j] = 0.0; - } + if (sliding_enabled || !on_floor) { + Vector3 slide_motion = result.remainder.slide(result.collision_normal); + if (slide_motion.dot(linear_velocity) > 0.0) { + motion = slide_motion; + } else { + motion = Vector3(); } } else { motion = result.remainder; @@ -1171,12 +1165,12 @@ bool CharacterBody3D::move_and_slide() { sliding_enabled = true; - if (!found_collision || motion == Vector3()) { + if (!collided || motion.is_equal_approx(Vector3())) { break; } } - if (was_on_floor && snap != Vector3()) { + if (was_on_floor && !on_floor && !snap.is_equal_approx(Vector3())) { // Apply snap. Transform3D gt = get_global_transform(); PhysicsServer3D::MotionResult result; @@ -1213,6 +1207,11 @@ bool CharacterBody3D::move_and_slide() { linear_velocity += current_floor_velocity; } + // Reset the gravity accumulation when touching the ground. + if (on_floor && linear_velocity.dot(up_direction) <= 0) { + linear_velocity = linear_velocity.slide(up_direction); + } + return motion_results.size() > 0; } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 661e0dc648..0dddb2b09a 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -97,6 +97,8 @@ Ref<Shader> ColorPicker::circle_shader; void ColorPicker::init_shaders() { wheel_shader.instantiate(); wheel_shader->set_code(R"( +// ColorPicker wheel shader. + shader_type canvas_item; void fragment() { @@ -119,6 +121,8 @@ void fragment() { circle_shader.instantiate(); circle_shader->set_code(R"( +// ColorPicker circle shader. + shader_type canvas_item; uniform float v = 1.0; diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 80e338c8e8..b4eec2530b 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -29,9 +29,9 @@ /*************************************************************************/ #include "animation.h" -#include "scene/scene_string_names.h" #include "core/math/geometry_3d.h" +#include "scene/scene_string_names.h" bool Animation::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; @@ -79,17 +79,16 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) { TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]); Vector<real_t> values = p_value; int vcount = values.size(); - ERR_FAIL_COND_V(vcount % 12, false); // should be multiple of 12 + ERR_FAIL_COND_V(vcount % TRANSFORM_TRACK_SIZE, false); const real_t *r = values.ptr(); - int transform3d_size = (int)sizeof(Transform3D); - - tt->transforms.resize(vcount / transform3d_size); + int64_t count = vcount / TRANSFORM_TRACK_SIZE; + tt->transforms.resize(count); - for (int i = 0; i < (vcount / transform3d_size); i++) { + for (int i = 0; i < count; i++) { TKey<TransformKey> &tk = tt->transforms.write[i]; - const real_t *ofs = &r[i * 12]; + const real_t *ofs = &r[i * TRANSFORM_TRACK_SIZE]; tk.time = ofs[0]; tk.transition = ofs[1]; @@ -356,7 +355,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { if (track_get_type(track) == TYPE_TRANSFORM3D) { Vector<real_t> keys; int kk = track_get_key_count(track); - keys.resize(kk * sizeof(Transform3D)); + keys.resize(kk * TRANSFORM_TRACK_SIZE); real_t *w = keys.ptrw(); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 6227f6967f..9a410bd566 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -92,6 +92,9 @@ private: Vector3 scale; }; + // Not necessarily the same size as Transform3D. The amount of numbers in Animation::Key and TransformKey. + const int32_t TRANSFORM_TRACK_SIZE = 12; + /* TRANSFORM TRACK */ struct TransformTrack : public Track { diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 4ad5f2a506..063a13efc0 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -1758,11 +1758,16 @@ void GradientTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture::get_gradient); ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture::set_width); + // The `get_width()` method is already exposed by the parent class Texture2D. + + ClassDB::bind_method(D_METHOD("set_use_hdr", "enabled"), &GradientTexture::set_use_hdr); + ClassDB::bind_method(D_METHOD("is_using_hdr"), &GradientTexture::is_using_hdr); ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr"); } void GradientTexture::set_gradient(Ref<Gradient> p_gradient) { @@ -1800,30 +1805,49 @@ void GradientTexture::_update() { return; } - Vector<uint8_t> data; - data.resize(width * 4); - { - uint8_t *wd8 = data.ptrw(); + if (use_hdr) { + // High dynamic range. + Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBAF)); Gradient &g = **gradient; - + // `create()` isn't available for non-uint8_t data, so fill in the data manually. for (int i = 0; i < width; i++) { float ofs = float(i) / (width - 1); - Color color = g.get_color_at_offset(ofs); + image->set_pixel(i, 0, g.get_color_at_offset(ofs)); + } - wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255)); - wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255)); - wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255)); - wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255)); + if (texture.is_valid()) { + RID new_texture = RS::get_singleton()->texture_2d_create(image); + RS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = RS::get_singleton()->texture_2d_create(image); + } + } else { + // Low dynamic range. "Overbright" colors will be clamped. + Vector<uint8_t> data; + data.resize(width * 4); + { + uint8_t *wd8 = data.ptrw(); + Gradient &g = **gradient; + + for (int i = 0; i < width; i++) { + float ofs = float(i) / (width - 1); + Color color = g.get_color_at_offset(ofs); + + wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255)); + wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255)); + wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255)); + wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255)); + } } - } - Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data)); + Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data)); - if (texture.is_valid()) { - RID new_texture = RS::get_singleton()->texture_2d_create(image); - RS::get_singleton()->texture_replace(texture, new_texture); - } else { - texture = RS::get_singleton()->texture_2d_create(image); + if (texture.is_valid()) { + RID new_texture = RS::get_singleton()->texture_2d_create(image); + RS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = RS::get_singleton()->texture_2d_create(image); + } } emit_changed(); @@ -1839,6 +1863,19 @@ int GradientTexture::get_width() const { return width; } +void GradientTexture::set_use_hdr(bool p_enabled) { + if (p_enabled == use_hdr) { + return; + } + + use_hdr = p_enabled; + _queue_update(); +} + +bool GradientTexture::is_using_hdr() const { + return use_hdr; +} + Ref<Image> GradientTexture::get_image() const { if (!texture.is_valid()) { return Ref<Image>(); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 2e97c2deb1..f6b991c335 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -686,6 +686,7 @@ private: bool update_pending = false; RID texture; int width = 2048; + bool use_hdr = false; void _queue_update(); void _update(); @@ -700,6 +701,9 @@ public: void set_width(int p_width); int get_width() const override; + void set_use_hdr(bool p_enabled); + bool is_using_hdr() const; + virtual RID get_rid() const override { return texture; } virtual int get_height() const override { return 1; } virtual bool has_alpha() const override { return true; } 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 be18a73989..a24860996c 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 @@ -683,6 +683,8 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin default_shader = storage->shader_allocate(); storage->shader_initialize(default_shader); storage->shader_set_code(default_shader, R"( +// Default 3D material shader (clustered). + shader_type spatial; void vertex() { @@ -712,6 +714,8 @@ void fragment() { storage->shader_initialize(overdraw_material_shader); // Use relatively low opacity so that more "layers" of overlapping objects can be distinguished. storage->shader_set_code(overdraw_material_shader, R"( +// 3D editor Overdraw debug draw mode shader (clustered). + shader_type spatial; render_mode blend_add, unshaded; 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 735014a2ec..04ad1a2724 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 @@ -673,6 +673,8 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p default_shader = storage->shader_allocate(); storage->shader_initialize(default_shader); storage->shader_set_code(default_shader, R"( +// Default 3D material shader (mobile). + shader_type spatial; void vertex() { @@ -701,6 +703,8 @@ void fragment() { storage->shader_initialize(overdraw_material_shader); // Use relatively low opacity so that more "layers" of overlapping objects can be distinguished. storage->shader_set_code(overdraw_material_shader, R"( +// 3D editor Overdraw debug draw mode shader (mobile). + shader_type spatial; render_mode blend_add, unshaded; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index f8aefdb29c..3af5047854 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2575,6 +2575,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) { storage->shader_initialize(default_canvas_group_shader); storage->shader_set_code(default_canvas_group_shader, R"( +// Default CanvasGroup shader. + shader_type canvas_item; void fragment() { diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 9e85608f1e..4165c3f7ba 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -855,6 +855,8 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) { storage->shader_initialize(sky_shader.default_shader); storage->shader_set_code(sky_shader.default_shader, R"( +// Default sky shader. + shader_type sky; void sky() { @@ -942,6 +944,8 @@ void sky() { storage->shader_initialize(sky_scene_state.fog_shader); storage->shader_set_code(sky_scene_state.fog_shader, R"( +// Default clear color sky shader. + shader_type sky; uniform vec4 clear_color; diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp index 8cc20618fc..14a5a01054 100644 --- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp @@ -9398,6 +9398,8 @@ RendererStorageRD::RendererStorageRD() { particles_shader.default_shader = shader_allocate(); shader_initialize(particles_shader.default_shader); shader_set_code(particles_shader.default_shader, R"( +// Default particles shader. + shader_type particles; void process() { |