diff options
25 files changed, 199 insertions, 154 deletions
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 1d2b5f19ee..c6448b1e44 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -452,8 +452,13 @@ bool InputEventKey::is_match(const Ref<InputEvent> &p_event, bool p_exact_match) return false; } - return keycode == key->keycode && - (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); + if (keycode == 0) { + return physical_keycode == key->physical_keycode && + (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); + } else { + return keycode == key->keycode && + (!p_exact_match || get_modifiers_mask() == key->get_modifiers_mask()); + } } void InputEventKey::_bind_methods() { diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml index 7c006ad3a6..f2a6e5b6f8 100644 --- a/doc/classes/DirectionalLight3D.xml +++ b/doc/classes/DirectionalLight3D.xml @@ -11,7 +11,7 @@ </tutorials> <members> <member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled" default="false"> - If [code]true[/code], shadow detail is sacrificed in exchange for smoother transitions between splits. + If [code]true[/code], shadow detail is sacrificed in exchange for smoother transitions between splits. This is ignored when [member directional_shadow_mode] is [code]SHADOW_ORTHOGONAL[/code]. </member> <member name="directional_shadow_fade_start" type="float" setter="set_param" getter="get_param" default="0.8"> Proportion of [member directional_shadow_max_distance] at which point the shadow starts to fade. At [member directional_shadow_max_distance] the shadow will disappear. @@ -29,7 +29,7 @@ The distance from camera to shadow split 1. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or [code]SHADOW_PARALLEL_4_SPLITS[/code]. </member> <member name="directional_shadow_split_2" type="float" setter="set_param" getter="get_param" default="0.2"> - The distance from shadow split 1 to split 2. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or [code]SHADOW_PARALLEL_4_SPLITS[/code]. + The distance from shadow split 1 to split 2. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]. </member> <member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5"> The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]. diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml index 6af6507606..5f342e6dc2 100644 --- a/doc/classes/EditorProperty.xml +++ b/doc/classes/EditorProperty.xml @@ -73,8 +73,8 @@ <member name="deletable" type="bool" setter="set_deletable" getter="is_deletable" default="false"> Used by the inspector, set to [code]true[/code] when the property can be deleted by the user. </member> - <member name="draw_red" type="bool" setter="set_draw_red" getter="is_draw_red" default="false"> - Used by the inspector, set to [code]true[/code] when the property must draw with error color. This is used for editable children's properties. + <member name="draw_warning" type="bool" setter="set_draw_warning" getter="is_draw_warning" default="false"> + Used by the inspector, set to [code]true[/code] when the property is drawn with the editor theme's warning color. This is used for editable children's properties. </member> <member name="keying" type="bool" setter="set_keying" getter="is_keying" default="false"> Used by the inspector, set to [code]true[/code] when the property can add keys for animation. diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml index 52359b0ede..dbda22d618 100644 --- a/doc/classes/Light3D.xml +++ b/doc/classes/Light3D.xml @@ -32,7 +32,7 @@ If [code]true[/code], the light only appears in the editor and will not be visible at runtime. </member> <member name="light_angular_distance" type="float" setter="set_param" getter="get_param" default="0.0"> - The light's angular size in degrees. Only available for [DirectionalLight3D]s. For reference, the Sun from the Earth is approximately [code]0.5[/code]. + The light's angular size in degrees. Increasing this will make shadows softer at greater distances. Only available for [DirectionalLight3D]s. For reference, the Sun from the Earth is approximately [code]0.5[/code]. </member> <member name="light_bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="Light3D.BakeMode" default="1"> The light's bake mode. See [enum BakeMode]. diff --git a/doc/classes/NavigationMesh.xml b/doc/classes/NavigationMesh.xml index e476949360..b100a20963 100644 --- a/doc/classes/NavigationMesh.xml +++ b/doc/classes/NavigationMesh.xml @@ -84,7 +84,7 @@ <member name="agent/max_slope" type="float" setter="set_agent_max_slope" getter="get_agent_max_slope" default="45.0"> The maximum slope that is considered walkable, in degrees. </member> - <member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="0.6"> + <member name="agent/radius" type="float" setter="set_agent_radius" getter="get_agent_radius" default="1.0"> The distance to erode/shrink the walkable area of the heightfield away from obstructions. [b]Note:[/b] While baking, this value will be rounded up to the nearest multiple of [member cell/size]. </member> diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml index e06dfee698..5bd6b0572c 100644 --- a/doc/classes/TextParagraph.xml +++ b/doc/classes/TextParagraph.xml @@ -199,7 +199,7 @@ Returns width (for horizontal layout) or height (for vertical) of the line of text. </description> </method> - <method name="get_non_wraped_size" qualifiers="const"> + <method name="get_non_wrapped_size" qualifiers="const"> <return type="Vector2" /> <description> Returns the size of the bounding box of the paragraph, without line breaks. diff --git a/doc/classes/XRInterfaceExtension.xml b/doc/classes/XRInterfaceExtension.xml index 3b5d8e2f10..d2bb6aa59a 100644 --- a/doc/classes/XRInterfaceExtension.xml +++ b/doc/classes/XRInterfaceExtension.xml @@ -81,11 +81,6 @@ <description> </description> </method> - <method name="_get_tracking_status" qualifiers="virtual const"> - <return type="int" /> - <description> - </description> - </method> <method name="_get_transform_for_view" qualifiers="virtual"> <return type="Transform3D" /> <argument index="0" name="view" type="int" /> diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 4d0f27c5d4..9f049a0e58 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -245,13 +245,15 @@ void EditorProperty::_notification(int p_what) { } Color color; - if (draw_red) { - color = get_theme_color(is_read_only() ? SNAME("readonly_error_color") : SNAME("error_color")); + if (draw_warning) { + color = get_theme_color(is_read_only() ? SNAME("readonly_warning_color") : SNAME("warning_color")); } else { color = get_theme_color(is_read_only() ? SNAME("readonly_color") : SNAME("property_color")); } if (label.find(".") != -1) { - color.a = 0.5; //this should be un-hacked honestly, as it's used for editor overrides + // FIXME: Move this to the project settings editor, as this is only used + // for project settings feature tag overrides. + color.a = 0.5; } int ofs = get_theme_constant(SNAME("font_offset")); @@ -625,8 +627,8 @@ bool EditorProperty::is_checked() const { return checked; } -void EditorProperty::set_draw_red(bool p_draw_red) { - draw_red = p_draw_red; +void EditorProperty::set_draw_warning(bool p_draw_warning) { + draw_warning = p_draw_warning; update(); } @@ -650,8 +652,8 @@ bool EditorProperty::is_keying() const { return keying; } -bool EditorProperty::is_draw_red() const { - return draw_red; +bool EditorProperty::is_draw_warning() const { + return draw_warning; } void EditorProperty::_focusable_focused(int p_index) { @@ -969,8 +971,8 @@ void EditorProperty::_bind_methods() { ClassDB::bind_method(D_METHOD("set_checked", "checked"), &EditorProperty::set_checked); ClassDB::bind_method(D_METHOD("is_checked"), &EditorProperty::is_checked); - ClassDB::bind_method(D_METHOD("set_draw_red", "draw_red"), &EditorProperty::set_draw_red); - ClassDB::bind_method(D_METHOD("is_draw_red"), &EditorProperty::is_draw_red); + ClassDB::bind_method(D_METHOD("set_draw_warning", "draw_warning"), &EditorProperty::set_draw_warning); + ClassDB::bind_method(D_METHOD("is_draw_warning"), &EditorProperty::is_draw_warning); ClassDB::bind_method(D_METHOD("set_keying", "keying"), &EditorProperty::set_keying); ClassDB::bind_method(D_METHOD("is_keying"), &EditorProperty::is_keying); @@ -993,7 +995,7 @@ void EditorProperty::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checkable"), "set_checkable", "is_checkable"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "checked"), "set_checked", "is_checked"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_red"), "set_draw_red", "is_draw_red"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_warning"), "set_draw_warning", "is_draw_warning"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keying"), "set_keying", "is_keying"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deletable"), "set_deletable", "is_deletable"); ADD_SIGNAL(MethodInfo("property_changed", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT))); @@ -1018,7 +1020,7 @@ EditorProperty::EditorProperty() { read_only = false; checkable = false; checked = false; - draw_red = false; + draw_warning = false; keying = false; deletable = false; keying_hover = false; @@ -2393,14 +2395,15 @@ void EditorInspector::update_tree() { valid_plugins.push_back(inspector_plugins[i]); } - // Decide if properties should be drawn in red. - bool draw_red = false; + // Decide if properties should be drawn with the warning color (yellow). + bool draw_warning = false; if (is_inside_tree()) { Node *nod = Object::cast_to<Node>(object); Node *es = EditorNode::get_singleton()->get_edited_scene(); if (nod && es != nod && nod->get_owner() != es) { - // Draw in red edited nodes that are not in the currently edited scene. - draw_red = true; + // Draw in warning color edited nodes that are not in the currently edited scene, + // as changes may be lost in the future. + draw_warning = true; } } @@ -2855,7 +2858,7 @@ void EditorInspector::update_tree() { editor_property_map[prop].push_back(ep); } } - ep->set_draw_red(draw_red); + ep->set_draw_warning(draw_warning); ep->set_use_folding(use_folding); ep->set_checkable(checkable); ep->set_checked(checked); diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index b71efe8f19..06af8566ff 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -74,7 +74,7 @@ private: bool read_only; bool checkable; bool checked; - bool draw_red; + bool draw_warning; bool keying; bool deletable; @@ -150,8 +150,8 @@ public: void set_checked(bool p_checked); bool is_checked() const; - void set_draw_red(bool p_draw_red); - bool is_draw_red() const; + void set_draw_warning(bool p_draw_warning); + bool is_draw_warning() const; void set_keying(bool p_keying); bool is_keying() const; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 2d4db48f2a..134f2ce202 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -431,7 +431,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { Color error_color = Color(1, 0.47, 0.42); Color property_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.5); Color readonly_color = property_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); - Color readonly_error_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); + Color readonly_warning_color = error_color.lerp(dark_theme ? Color(0, 0, 0) : Color(1, 1, 1), 0.5); if (!dark_theme) { // Darken some colors to be readable on a light background @@ -445,7 +445,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("error_color", "Editor", error_color); theme->set_color("property_color", "Editor", property_color); theme->set_color("readonly_color", "Editor", readonly_color); - theme->set_color("readonly_error_color", "EditorProperty", readonly_error_color); if (!dark_theme) { theme->set_color("vulkan_color", "Editor", Color::hex(0xad1128ff)); @@ -819,10 +818,10 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); theme->set_constant("vseparation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); - theme->set_color("error_color", "EditorProperty", error_color); + theme->set_color("warning_color", "EditorProperty", warning_color); theme->set_color("property_color", "EditorProperty", property_color); theme->set_color("readonly_color", "EditorProperty", readonly_color); - theme->set_color("readonly_error_color", "EditorProperty", readonly_error_color); + theme->set_color("readonly_warning_color", "EditorProperty", readonly_warning_color); Color inspector_section_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.35); theme->set_color("font_color", "EditorInspectorSection", inspector_section_color); diff --git a/editor/editor_toaster.cpp b/editor/editor_toaster.cpp index 0d45a7f1d8..9de0ea40fe 100644 --- a/editor/editor_toaster.cpp +++ b/editor/editor_toaster.cpp @@ -35,7 +35,7 @@ #include "editor_toaster.h" -EditorToaster *EditorToaster::singleton; +EditorToaster *EditorToaster::singleton = nullptr; void EditorToaster::_notification(int p_what) { switch (p_what) { @@ -90,8 +90,10 @@ void EditorToaster::_notification(int p_what) { // Hide element if it is not visible anymore. if (modulate.a <= 0) { - element.key->hide(); - needs_update = true; + if (element.key->is_visible()) { + element.key->hide(); + needs_update = true; + } } } @@ -141,7 +143,7 @@ void EditorToaster::_notification(int p_what) { } void EditorToaster::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, bool p_editor_notify, ErrorHandlerType p_type) { - if (!EditorToaster::get_singleton()) { + if (!EditorToaster::get_singleton() || !EditorToaster::get_singleton()->is_inside_tree()) { return; } diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 32a8bbf406..0096152cfe 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2228,18 +2228,28 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_down", p_event)) { cursor.x_rot -= Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_up", p_event)) { cursor.x_rot += Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_right", p_event)) { cursor.y_rot -= Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_left", p_event)) { cursor.y_rot += Math_PI / 12.0; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/orbit_view_180", p_event)) { cursor.y_rot += Math_PI; + view_type = VIEW_TYPE_USER; + _update_name(); } if (ED_IS_SHORTCUT("spatial_editor/focus_origin", p_event)) { _menu_option(VIEW_CENTER_TO_ORIGIN); diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html index 2cae215951..69e267f665 100644 --- a/misc/dist/html/editor.html +++ b/misc/dist/html/editor.html @@ -14,7 +14,7 @@ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="msapplication-starturl" content="/latest" /> <meta property="og:site_name" content="Godot Engine Web Editor" /> - <meta property="og:url" name="twitter:url" content="https://editor.godotengine.org/releases/latest/" /> + <meta property="og:url" name="twitter:url" content="https://editor.godotengine.org/releases/latest/" /> <meta property="og:title" name="twitter:title" content="Free and open source 2D and 3D game engine" /> <meta property="og:description" name="twitter:description" content="Use the Godot Engine editor directly in your web browser, without having to install anything." /> <meta property="og:image" name="twitter:image" content="https://godotengine.org/themes/godotengine/assets/og_image.png" /> @@ -269,11 +269,6 @@ <div id="tabs"> <div id="tab-loader"> <div style="color: #e0e0e0;" id="persistence"> - <label for="videoMode" style="display: none;">Select video driver:</label><br /> - <select id="videoMode" style="display: none;"> - <option value="GLES2" selected="selected">WebGL</option> - <option value="GLES3">WebGL 2</option> - </select> <br /> <img src="logo.svg" alt="Godot Engine logo" width="1024" height="414" style="width: auto; height: auto; max-width: 85%; max-height: 250px" /> <br /> @@ -283,6 +278,14 @@ <br /> <br /> <br /> + <label for="videoMode" style="margin-right: 1rem">Video driver:</label> + <select id="videoMode"> + <option value="" selected="selected">Auto</option> + <option value="GLES2">WebGL</option> + <option value="GLES3">WebGL 2</option> + </select> + <br /> + <br /> <label for="zip-file" style="margin-right: 1rem">Preload project ZIP:</label> <input id="zip-file" type="file" name="files" style="margin-bottom: 1rem"/> <br /> <a href="demo.zip">(Try this for example)</a> @@ -348,7 +351,7 @@ var game = null; var setStatusMode; var setStatusNotice; - var video_driver = "GLES2"; + var video_driver = ""; function clearPersistence() { function deleteDB(path) { @@ -479,6 +482,15 @@ animationCallbacks.push(adjustCanvasDimensions); adjustCanvasDimensions(); + function replaceCanvas(from) { + const out = document.createElement("canvas"); + out.id = from.id; + out.tabIndex = from.tabIndex; + from.parentNode.replaceChild(out, from); + lastScale = 0; + return out; + } + setStatusMode = function setStatusMode(mode) { if (statusMode === mode || !initializing) return; @@ -534,6 +546,7 @@ 'canvas': gameCanvas, 'canvasResizePolicy': 1, 'onExit': function () { + gameCanvas = replaceCanvas(gameCanvas); setGameTabEnabled(false); showTab('editor'); game = null; @@ -548,7 +561,7 @@ const is_editor = args.filter(function(v) { return v == '--editor' || v == '-e' }).length != 0; const is_project_manager = args.filter(function(v) { return v == '--project-manager' }).length != 0; const is_game = !is_editor && !is_project_manager; - if (is_project_manager) { + if (video_driver) { args.push('--video-driver', video_driver); } if (is_game) { @@ -561,7 +574,7 @@ showTab('game'); game.init().then(function() { requestAnimationFrame(function() { - game.start({'args': args}).then(function() { + game.start({'args': args, 'canvas': gameCanvas}).then(function() { gameCanvas.focus(); }); }); @@ -576,7 +589,7 @@ showTab('loader'); setLoaderEnabled(true); }; - editor.start({'args': args, 'persistentDrops': is_project_manager}); + editor.start({'args': args, 'persistentDrops': is_project_manager, 'canvas': editorCanvas}); }); }, 0); OnEditorExit = null; @@ -603,6 +616,7 @@ 'canvas': editorCanvas, 'canvasResizePolicy': 0, 'onExit': function() { + editorCanvas = replaceCanvas(editorCanvas); if (OnEditorExit) { OnEditorExit(); } @@ -634,10 +648,14 @@ } catch(e) { // File exists } - //selectVideoMode(); + selectVideoMode(); showTab('editor'); setLoaderEnabled(false); - editor.start({'args': ['--project-manager', '--video-driver', video_driver], 'persistentDrops': true}).then(function() { + const args = ['--project-manager']; + if (video_driver) { + args.push('--video-driver', video_driver); + } + editor.start({'args': args, 'persistentDrops': true}).then(function() { setStatusMode('hidden'); initializing = false; }); diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index ba4ef3be8d..37e969db4d 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -611,6 +611,61 @@ void LightmapperRD::_raster_geometry(RenderingDevice *rd, Size2i atlas_size, int } } +LightmapperRD::BakeError LightmapperRD::_dilate(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices) { + Vector<RD::Uniform> uniforms; + { + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_IMAGE; + u.binding = 0; + u.ids.push_back(dest_light_tex); + uniforms.push_back(u); + } + { + RD::Uniform u; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + u.binding = 1; + u.ids.push_back(source_light_tex); + uniforms.push_back(u); + } + } + + RID compute_shader_dilate = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("dilate")); + ERR_FAIL_COND_V(compute_shader_dilate.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen + RID compute_shader_dilate_pipeline = rd->compute_pipeline_create(compute_shader_dilate); + + RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_dilate, 1); + + RD::ComputeListID compute_list = rd->compute_list_begin(); + rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_dilate_pipeline); + rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0); + rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1); + push_constant.region_ofs[0] = 0; + push_constant.region_ofs[1] = 0; + Vector3i group_size((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1); //restore group size + + for (int i = 0; i < atlas_slices; i++) { + push_constant.atlas_slice = i; + rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); + rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z); + //no barrier, let them run all together + } + rd->compute_list_end(); + rd->free(compute_shader_dilate); + +#ifdef DEBUG_TEXTURES + for (int i = 0; i < atlas_slices; i++) { + Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i); + Ref<Image> img; + img.instantiate(); + img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s); + img->convert(Image::FORMAT_RGBA8); + img->save_png("res://5_dilated_" + itos(i) + ".png"); + } +#endif + return BAKE_OK; +} + LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function, void *p_bake_userdata) { if (p_step_function) { p_step_function(0.0, TTR("Begin Bake"), p_bake_userdata, true); @@ -943,11 +998,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d ERR_FAIL_COND_V(compute_shader_secondary.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen RID compute_shader_secondary_pipeline = rd->compute_pipeline_create(compute_shader_secondary); - // Dilate - RID compute_shader_dilate = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("dilate")); - ERR_FAIL_COND_V(compute_shader_dilate.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen - RID compute_shader_dilate_pipeline = rd->compute_pipeline_create(compute_shader_dilate); - // Light probes RID compute_shader_light_probes = rd->shader_create_from_spirv(compute_shader->get_spirv_stages("light_probes")); ERR_FAIL_COND_V(compute_shader_light_probes.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen @@ -959,7 +1009,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d rd->free(compute_shader_unocclude); \ rd->free(compute_shader_primary); \ rd->free(compute_shader_secondary); \ - rd->free(compute_shader_dilate); \ rd->free(compute_shader_light_probes); PushConstant push_constant; @@ -1270,7 +1319,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d push_constant.environment_xform[3] = 0.0f; } - /* LIGHPROBES */ + /* LIGHTPROBES */ RID light_probe_buffer; @@ -1377,6 +1426,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d } #endif + { + SWAP(light_accum_tex, light_accum_tex2); + BakeError error = _dilate(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices * (p_bake_sh ? 4 : 1)); + if (unlikely(error != BAKE_OK)) { + return error; + } + } + /* DENOISE */ if (p_use_denoiser) { @@ -1409,58 +1466,14 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d } } } - } -#ifdef DEBUG_TEXTURES - - for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) { - Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i); - Ref<Image> img; - img.instantiate(); - img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s); - img->save_exr("res://4_light_secondary_" + itos(i) + ".exr", false); - } -#endif - - /* DILATE LIGHTMAP */ - { - SWAP(light_accum_tex, light_accum_tex2); - - Vector<RD::Uniform> uniforms; { - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 0; - u.ids.push_back(light_accum_tex); - uniforms.push_back(u); - } - { - RD::Uniform u; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - u.binding = 1; - u.ids.push_back(light_accum_tex2); - uniforms.push_back(u); + SWAP(light_accum_tex, light_accum_tex2); + BakeError error = _dilate(rd, compute_shader, compute_base_uniform_set, push_constant, light_accum_tex2, light_accum_tex, atlas_size, atlas_slices * (p_bake_sh ? 4 : 1)); + if (unlikely(error != BAKE_OK)) { + return error; } } - - RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_dilate, 1); - - RD::ComputeListID compute_list = rd->compute_list_begin(); - rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_dilate_pipeline); - rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0); - rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1); - push_constant.region_ofs[0] = 0; - push_constant.region_ofs[1] = 0; - group_size = Vector3i((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1); //restore group size - - for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) { - push_constant.atlas_slice = i; - rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant)); - rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z); - //no barrier, let them run all together - } - rd->compute_list_end(); } #ifdef DEBUG_TEXTURES @@ -1470,8 +1483,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d Ref<Image> img; img.instantiate(); img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s); - img->convert(Image::FORMAT_RGBA8); - img->save_png("res://5_dilated_" + itos(i) + ".png"); + img->save_exr("res://4_light_secondary_" + itos(i) + ".exr", false); } #endif diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index a6a3740051..e1657b2069 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -36,6 +36,7 @@ #include "scene/resources/mesh.h" #include "servers/rendering/rendering_device.h" +class RDShaderFile; class LightmapperRD : public Lightmapper { GDCLASS(LightmapperRD, Lightmapper) @@ -231,6 +232,8 @@ class LightmapperRD : public Lightmapper { void _create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, Vector<Probe> &probe_positions, GenerateProbes p_generate_probes, Vector<int> &slice_triangle_count, Vector<int> &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &lights_buffer, RID &triangle_cell_indices_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata); void _raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector<int> slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform); + BakeError _dilate(RenderingDevice *rd, Ref<RDShaderFile> &compute_shader, RID &compute_base_uniform_set, PushConstant &push_constant, RID &source_light_tex, RID &dest_light_tex, const Size2i &atlas_size, int atlas_slices); + public: virtual void add_mesh(const MeshData &p_mesh) override; virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) override; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 4588966d88..93d1eb5ba4 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -486,7 +486,7 @@ void RichTextLabel::_shape_line(ItemFrame *p_frame, int p_line, const Ref<Font> remaining_characters -= cell_ch; table->columns.write[column].min_width = MAX(table->columns[column].min_width, ceil(frame->lines[i].text_buf->get_size().x)); - table->columns.write[column].max_width = MAX(table->columns[column].max_width, ceil(frame->lines[i].text_buf->get_non_wraped_size().x)); + table->columns.write[column].max_width = MAX(table->columns[column].max_width, ceil(frame->lines[i].text_buf->get_non_wrapped_size().x)); } idx++; } diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index f03eebd543..55c18980f9 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -4039,7 +4039,7 @@ int TextEdit::get_visible_line_count() const { } int TextEdit::get_total_visible_line_count() const { - /* Returns the total number of (lines + wraped - hidden). */ + /* Returns the total number of (lines + wrapped - hidden). */ if (!_is_hiding_enabled() && get_line_wrapping_mode() == LineWrappingMode::LINE_WRAPPING_NONE) { return text.size(); } diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h index 1cdf7a07ed..009239838f 100644 --- a/scene/resources/navigation_mesh.h +++ b/scene/resources/navigation_mesh.h @@ -85,7 +85,7 @@ protected: float cell_size = 0.3f; float cell_height = 0.2f; float agent_height = 2.0f; - float agent_radius = 0.6f; + float agent_radius = 1.0f; float agent_max_climb = 0.9f; float agent_max_slope = 45.0f; float region_min_size = 8.0f; diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index b2e18e2451..fae1de94d3 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -84,7 +84,7 @@ void TextParagraph::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "width"), "set_width", "get_width"); - ClassDB::bind_method(D_METHOD("get_non_wraped_size"), &TextParagraph::get_non_wraped_size); + ClassDB::bind_method(D_METHOD("get_non_wrapped_size"), &TextParagraph::get_non_wrapped_size); ClassDB::bind_method(D_METHOD("get_size"), &TextParagraph::get_size); ClassDB::bind_method(D_METHOD("get_rid"), &TextParagraph::get_rid); @@ -417,7 +417,7 @@ float TextParagraph::get_width() const { return width; } -Size2 TextParagraph::get_non_wraped_size() const { +Size2 TextParagraph::get_non_wrapped_size() const { const_cast<TextParagraph *>(this)->_shape_lines(); if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom); diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index 69c50559df..701c9a17cd 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -120,7 +120,7 @@ public: void set_max_lines_visible(int p_lines); int get_max_lines_visible() const; - Size2 get_non_wraped_size() const; + Size2 get_non_wrapped_size() const; Size2 get_size() const; 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 6b84ab908d..0deb822e86 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -328,6 +328,8 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p push_constant.uv_offset = 0; } + bool should_request_redraw = false; + for (uint32_t i = p_from_element; i < p_to_element; i++) { const GeometryInstanceSurfaceDataCache *surf = p_params->elements[i]; const RenderElementInfo &element_info = p_params->element_info[i]; @@ -365,6 +367,11 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p continue; } + //request a redraw if one of the shaders uses TIME + if (shader->uses_time) { + should_request_redraw = true; + } + //find cull variant SceneShaderForwardClustered::ShaderData::CullVariant cull_variant; @@ -500,6 +507,11 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instance_count); i += element_info.repeat - 1; //skip equal elements } + + // Make the actual redraw request + if (should_request_redraw) { + RenderingServerDefault::redraw_request(); + } } void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 329deeb1ae..d128578d0b 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3026,7 +3026,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const RS::LightDirectionalShadowMode smode = storage->light_directional_get_shadow_mode(base); int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3); - light_data.blend_splits = storage->light_directional_get_blend_splits(base); + light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && storage->light_directional_get_blend_splits(base); for (int j = 0; j < 4; j++) { Rect2 atlas_rect = li->shadow_transform[j].atlas_rect; CameraMatrix matrix = li->shadow_transform[j].camera; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 5261868155..987960069b 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -1270,21 +1270,21 @@ void main() { float shadow = 1.0; - //version with soft shadows, more expensive if (directional_lights.data[i].shadow_enabled) { - if (sc_use_directional_soft_shadows && directional_lights.data[i].softshadow_angle > 0) { - float depth_z = -vertex.z; - - vec3 shadow_color = vec3(0.0); - vec3 light_dir = directional_lights.data[i].direction; + float depth_z = -vertex.z; + vec3 light_dir = directional_lights.data[i].direction; + vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))); -#define BIAS_FUNC(m_var, m_idx) \ - m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ - vec3 normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))) * directional_lights.data[i].shadow_normal_bias[m_idx]; \ - normal_bias -= light_dir * dot(light_dir, normal_bias); \ +#define BIAS_FUNC(m_var, m_idx) \ + m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ + vec3 normal_bias = base_normal_bias * directional_lights.data[i].shadow_normal_bias[m_idx]; \ + normal_bias -= light_dir * dot(light_dir, normal_bias); \ m_var.xyz += normal_bias; - uint blend_index = 0; + //version with soft shadows, more expensive + if (sc_use_directional_soft_shadows && directional_lights.data[i].softshadow_angle > 0) { + uint blend_count = 0; + const uint blend_max = directional_lights.data[i].blend_splits ? 2 : 1; if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { vec4 v = vec4(vertex, 1.0); @@ -1299,10 +1299,10 @@ void main() { float test_radius = (range_pos - range_begin) * directional_lights.data[i].softshadow_angle; vec2 tex_scale = directional_lights.data[i].uv_scale1 * test_radius; shadow = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - blend_index++; + blend_count++; } - if (blend_index < 2 && depth_z < directional_lights.data[i].shadow_split_offsets.y) { + if (blend_count < blend_max && depth_z < directional_lights.data[i].shadow_split_offsets.y) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 1) @@ -1316,7 +1316,7 @@ void main() { vec2 tex_scale = directional_lights.data[i].uv_scale2 * test_radius; float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - if (blend_index == 0) { + if (blend_count == 0) { shadow = s; } else { //blend @@ -1324,10 +1324,10 @@ void main() { shadow = mix(shadow, s, blend); } - blend_index++; + blend_count++; } - if (blend_index < 2 && depth_z < directional_lights.data[i].shadow_split_offsets.z) { + if (blend_count < blend_max && depth_z < directional_lights.data[i].shadow_split_offsets.z) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 2) @@ -1341,7 +1341,7 @@ void main() { vec2 tex_scale = directional_lights.data[i].uv_scale3 * test_radius; float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - if (blend_index == 0) { + if (blend_count == 0) { shadow = s; } else { //blend @@ -1349,10 +1349,10 @@ void main() { shadow = mix(shadow, s, blend); } - blend_index++; + blend_count++; } - if (blend_index < 2) { + if (blend_count < blend_max) { vec4 v = vec4(vertex, 1.0); BIAS_FUNC(v, 3) @@ -1366,7 +1366,7 @@ void main() { vec2 tex_scale = directional_lights.data[i].uv_scale4 * test_radius; float s = sample_directional_soft_shadow(directional_shadow_atlas, pssm_coord.xyz, tex_scale * directional_lights.data[i].soft_shadow_scale); - if (blend_index == 0) { + if (blend_count == 0) { shadow = s; } else { //blend @@ -1375,21 +1375,9 @@ void main() { } } -#undef BIAS_FUNC } else { //no soft shadows - float depth_z = -vertex.z; - vec4 pssm_coord; - vec3 light_dir = directional_lights.data[i].direction; - vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp)))); - -#define BIAS_FUNC(m_var, m_idx) \ - m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \ - vec3 normal_bias = base_normal_bias * directional_lights.data[i].shadow_normal_bias[m_idx]; \ - normal_bias -= light_dir * dot(light_dir, normal_bias); \ - m_var.xyz += normal_bias; - if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { vec4 v = vec4(vertex, 1.0); @@ -1448,11 +1436,11 @@ void main() { float shadow2 = sample_directional_pcf_shadow(directional_shadow_atlas, scene_data.directional_shadow_pixel_size * directional_lights.data[i].soft_shadow_scale, pssm_coord); shadow = mix(shadow, shadow2, pssm_blend); } + } - shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance + shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, vertex.z)); //done with negative values for performance #undef BIAS_FUNC - } } // shadows if (i < 4) { diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index bae98f8884..a7886bb6b1 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2076,7 +2076,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in // This trick here is what stabilizes the shadow (make potential jaggies to not move) // at the cost of some wasted resolution. Still, the quality increase is very well worth it. - const real_t unit = radius * 2.0 / texture_size; + const real_t unit = (radius + soft_shadow_expand) * 2.0 / texture_size; x_max_cam = Math::snapped(x_vec.dot(center) + radius + soft_shadow_expand, unit); x_min_cam = Math::snapped(x_vec.dot(center) - radius - soft_shadow_expand, unit); y_max_cam = Math::snapped(y_vec.dot(center) + radius + soft_shadow_expand, unit); diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp index 341ba32245..80576ac607 100644 --- a/servers/xr/xr_interface_extension.cpp +++ b/servers/xr/xr_interface_extension.cpp @@ -41,8 +41,6 @@ void XRInterfaceExtension::_bind_methods() { GDVIRTUAL_BIND(_initialize); GDVIRTUAL_BIND(_uninitialize); - GDVIRTUAL_BIND(_get_tracking_status); - GDVIRTUAL_BIND(_supports_play_area_mode, "mode"); GDVIRTUAL_BIND(_get_play_area_mode); GDVIRTUAL_BIND(_set_play_area_mode, "mode"); |