From ce2c38602a13703eb5fef8ac83fb228e7b45cff3 Mon Sep 17 00:00:00 2001 From: Zi Ye Date: Wed, 12 Feb 2025 02:18:50 -0600 Subject: [PATCH] Added project settings to set default preview sun and environment. Added shadow toggle and revert buttons. Made default apply to new scenes. --- doc/classes/ProjectSettings.xml | 39 ++++++ editor/plugins/node_3d_editor_plugin.cpp | 150 ++++++++++++++++------- editor/plugins/node_3d_editor_plugin.h | 14 ++- editor/register_editor_types.cpp | 14 +++ 4 files changed, 169 insertions(+), 48 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 79bf8975411..1410e57bc26 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -955,6 +955,45 @@ Directory that contains the [code].sln[/code] file. By default, the [code].sln[/code] files is in the root of the project directory, next to the [code]project.godot[/code] and [code].csproj[/code] files. Changing this value allows setting up a multi-project scenario where there are multiple [code].csproj[/code]. Keep in mind that the Godot project is considered one of the C# projects in the workspace and it's root directory should contain the [code]project.godot[/code] and [code].csproj[/code] next to each other. + + If [code]true[/code], ambient occlusion is enabled by default for the preview environment in the 3D editor. + + + If [code]true[/code], global illumination is enabled by default for the preview environment in the 3D editor. + + + If [code]true[/code], glow is enabled by default for the preview environment in the 3D editor. + + + Default ground color for the preview environment in the 3D editor. + + + Default sky color for the preview environment in the 3D editor. + + + Default sky energy multiplier for the preview environment in the 3D editor. + + + If [code]true[/code], tonemapping is enabled by default for the preview environment in the 3D editor. + + + Default altitude (in degrees) for the preview sun in the 3D editor. + + + Default azimuth (in degrees) for the preview sun in the 3D editor. + + + Default color for the preview sun in the 3D editor. + + + Default energy for the preview sun in the 3D editor. + + + If [code]true[/code], shadows are enabled by default for the preview sun in the 3D editor. + + + Default max shadow distance for the preview sun in the 3D editor. + If [code]true[/code], text resource ([code]tres[/code]) and text scene ([code]tscn[/code]) files are converted to their corresponding binary format on export. This decreases file sizes and speeds up loading slightly. [b]Note:[/b] Because a resource's file extension may change in an exported project, it is heavily recommended to use [method @GDScript.load] or [ResourceLoader] instead of [FileAccess] to load resources dynamically. diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 058adbdb197..64bda8e40e3 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2840,6 +2840,10 @@ void Node3DEditorPlugin::edited_scene_changed() { viewport->notification(Control::NOTIFICATION_VISIBILITY_CHANGED); } } + + if (get_tree()->get_edited_scene_root() == nullptr) { + spatial_editor->set_state(Dictionary()); + } } void Node3DEditorViewport::_project_settings_changed() { @@ -4268,7 +4272,6 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) { previewing->connect(SceneStringName(tree_exiting), callable_mp(this, &Node3DEditorViewport::_preview_exited_scene)); RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), previewing->get_camera()); //replace surface->queue_redraw(); - previewing_camera = true; preview_camera->set_pressed(true); preview_camera->show(); } @@ -6456,12 +6459,13 @@ Dictionary Node3DEditor::get_state() const { pd["environ_sky_color"] = environ_sky_color->get_pick_color(); pd["environ_ground_color"] = environ_ground_color->get_pick_color(); - pd["environ_energy"] = environ_energy->get_value(); + pd["environ_energy"] = environ_sky_energy->get_value(); pd["environ_glow_enabled"] = environ_glow_button->is_pressed(); pd["environ_tonemap_enabled"] = environ_tonemap_button->is_pressed(); pd["environ_ao_enabled"] = environ_ao_button->is_pressed(); pd["environ_gi_enabled"] = environ_gi_button->is_pressed(); - pd["sun_max_distance"] = sun_max_distance->get_value(); + pd["sun_shadow_enabled"] = sun_shadow_enabled->is_pressed(); + pd["sun_shadow_max_distance"] = sun_shadow_max_distance->get_value(); pd["sun_color"] = sun_color->get_pick_color(); pd["sun_energy"] = sun_energy->get_value(); @@ -6588,12 +6592,13 @@ void Node3DEditor::set_state(const Dictionary &p_state) { environ_sky_color->set_pick_color(pd["environ_sky_color"]); environ_ground_color->set_pick_color(pd["environ_ground_color"]); - environ_energy->set_value(pd["environ_energy"]); - environ_glow_button->set_pressed(pd["environ_glow_enabled"]); + environ_sky_energy->set_value(pd["environ_energy"]); + environ_glow_button->set_pressed(pd["environ_glow_enabled"] && OS::get_singleton()->get_current_rendering_method() != "gl_compatibility"); environ_tonemap_button->set_pressed(pd["environ_tonemap_enabled"]); environ_ao_button->set_pressed(pd["environ_ao_enabled"]); environ_gi_button->set_pressed(pd["environ_gi_enabled"]); - sun_max_distance->set_value(pd["sun_max_distance"]); + sun_shadow_enabled->set_pressed(pd["sun_shadow_enabled"]); + sun_shadow_max_distance->set_value(pd["sun_shadow_max_distance"]); sun_color->set_pick_color(pd["sun_color"]); sun_energy->set_value(pd["sun_energy"]); @@ -8085,6 +8090,18 @@ void Node3DEditor::_sun_environ_settings_pressed() { sun_environ_popup->grab_focus(); } +void Node3DEditor::_revert_preview_sun() { + _load_default_preview_settings(true, false); + _preview_settings_changed(); + _update_preview_environment(); +} + +void Node3DEditor::_revert_preview_environ() { + _load_default_preview_settings(false, true); + _preview_settings_changed(); + _update_preview_environment(); +} + void Node3DEditor::_add_sun_to_scene(bool p_already_added_environment) { sun_environ_popup->hide(); @@ -8181,9 +8198,21 @@ void Node3DEditor::_update_theme() { environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor)))); environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), EditorStringName(Editor)))); + sun_revert->set_button_icon(get_editor_theme_icon(SNAME("Reload"))); + sun_add_to_scene->set_button_icon(get_editor_theme_icon(SNAME("Add"))); + environ_revert->set_button_icon(get_editor_theme_icon(SNAME("Reload"))); + environ_add_to_scene->set_button_icon(get_editor_theme_icon(SNAME("Add"))); + context_toolbar_panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SNAME("ContextualToolbar"), EditorStringName(EditorStyles))); } +void Node3DEditor::_project_settings_changed() { + update_all_gizmos(nullptr); + _load_default_preview_settings(sun_revert->is_disabled(), environ_revert->is_disabled()); + _preview_settings_changed(); + _update_preview_environment(); +} + void Node3DEditor::_notification(int p_what) { switch (p_what) { case NOTIFICATION_READY: { @@ -8201,7 +8230,7 @@ void Node3DEditor::_notification(int p_what) { sun_state->set_custom_minimum_size(sun_vb->get_combined_minimum_size()); environ_state->set_custom_minimum_size(environ_vb->get_combined_minimum_size()); - ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Node3DEditor::update_all_gizmos).bind(Variant())); + ProjectSettings::get_singleton()->connect("settings_changed", callable_mp(this, &Node3DEditor::_project_settings_changed)); } break; case NOTIFICATION_ENTER_TREE: { @@ -8667,13 +8696,23 @@ void Node3DEditor::_preview_settings_changed() { t.basis = Basis::from_euler(Vector3(sun_rotation.x, sun_rotation.y, 0)); preview_sun->set_transform(t); sun_direction->queue_redraw(); + preview_sun->set_visible(sun_energy->get_value() > 0); + preview_sun->set_shadow(sun_shadow_enabled->is_pressed()); preview_sun->set_param(Light3D::PARAM_ENERGY, sun_energy->get_value()); - preview_sun->set_param(Light3D::PARAM_SHADOW_MAX_DISTANCE, sun_max_distance->get_value()); + preview_sun->set_param(Light3D::PARAM_SHADOW_MAX_DISTANCE, sun_shadow_max_distance->get_value()); preview_sun->set_color(sun_color->get_pick_color()); + + sun_revert->set_disabled( + Math::is_equal_approx(sun_angle_altitude->get_value(), GLOBAL_GET("editor/3d/preview_sun/default_angle_altitude")) && + Math::is_equal_approx(sun_angle_azimuth->get_value(), GLOBAL_GET("editor/3d/preview_sun/default_angle_azimuth")) && + sun_color->get_pick_color().is_equal_approx(GLOBAL_GET("editor/3d/preview_sun/default_color")) && + Math::is_equal_approx(sun_energy->get_value(), GLOBAL_GET("editor/3d/preview_sun/default_energy")) && + sun_shadow_enabled->is_pressed() == (bool)GLOBAL_GET("editor/3d/preview_sun/default_shadow_enabled") && + Math::is_equal_approx(sun_shadow_max_distance->get_value(), GLOBAL_GET("editor/3d/preview_sun/default_shadow_max_distance"))); } { //preview env - sky_material->set_energy_multiplier(environ_energy->get_value()); + sky_material->set_energy_multiplier(environ_sky_energy->get_value()); Color hz_color = environ_sky_color->get_pick_color().lerp(environ_ground_color->get_pick_color(), 0.5); float hz_lum = hz_color.get_luminance() * 3.333; hz_color = hz_color.lerp(Color(hz_lum, hz_lum, hz_lum), 0.5); @@ -8686,36 +8725,41 @@ void Node3DEditor::_preview_settings_changed() { environment->set_glow_enabled(environ_glow_button->is_pressed()); environment->set_sdfgi_enabled(environ_gi_button->is_pressed()); environment->set_tonemapper(environ_tonemap_button->is_pressed() ? Environment::TONE_MAPPER_FILMIC : Environment::TONE_MAPPER_LINEAR); + + environ_revert->set_disabled( + environ_sky_color->get_pick_color().is_equal_approx(GLOBAL_GET("editor/3d/preview_environment/default_sky_color")) && + environ_ground_color->get_pick_color().is_equal_approx(GLOBAL_GET("editor/3d/preview_environment/default_ground_color")) && + Math::is_equal_approx(environ_sky_energy->get_value(), GLOBAL_GET("editor/3d/preview_environment/default_sky_energy")) && + environ_glow_button->is_pressed() == (bool)GLOBAL_GET("editor/3d/preview_environment/default_glow") && + environ_tonemap_button->is_pressed() == (bool)GLOBAL_GET("editor/3d/preview_environment/default_tonemap") && + environ_ao_button->is_pressed() == (bool)GLOBAL_GET("editor/3d/preview_environment/default_ao") && + environ_gi_button->is_pressed() == (bool)GLOBAL_GET("editor/3d/preview_environment/default_gi")); } } -void Node3DEditor::_load_default_preview_settings() { +void Node3DEditor::_load_default_preview_settings(bool p_sun, bool p_environ) { sun_environ_updating = true; - // These default rotations place the preview sun at an angular altitude - // of 60 degrees (must be negative) and an azimuth of 30 degrees clockwise - // from north (or 150 CCW from south), from north east, facing south west. - // On any not-tidally-locked planet, a sun would have an angular altitude - // of 60 degrees as the average of all points on the sphere at noon. - // The azimuth choice is arbitrary, but ideally shouldn't be on an axis. - sun_rotation = Vector2(-Math::deg_to_rad(60.0), Math::deg_to_rad(150.0)); - - sun_angle_altitude->set_value(-Math::rad_to_deg(sun_rotation.x)); - sun_angle_azimuth->set_value(180.0 - Math::rad_to_deg(sun_rotation.y)); - sun_direction->queue_redraw(); - environ_sky_color->set_pick_color(Color(0.385, 0.454, 0.55)); - environ_ground_color->set_pick_color(Color(0.2, 0.169, 0.133)); - environ_energy->set_value(1.0); - if (OS::get_singleton()->get_current_rendering_method() != "gl_compatibility") { - environ_glow_button->set_pressed(true); + if (p_sun) { + sun_angle_altitude->set_value(GLOBAL_GET("editor/3d/preview_sun/default_angle_altitude")); + sun_angle_azimuth->set_value(GLOBAL_GET("editor/3d/preview_sun/default_angle_azimuth")); + sun_rotation = Vector2(-Math::deg_to_rad(sun_angle_altitude->get_value()), Math::deg_to_rad(180.0 - sun_angle_azimuth->get_value())); + sun_color->set_pick_color(GLOBAL_GET("editor/3d/preview_sun/default_color")); + sun_energy->set_value(GLOBAL_GET("editor/3d/preview_sun/default_energy")); + sun_shadow_enabled->set_pressed(GLOBAL_GET("editor/3d/preview_sun/default_shadow_enabled")); + sun_shadow_max_distance->set_value(GLOBAL_GET("editor/3d/preview_sun/default_shadow_max_distance")); + sun_direction->queue_redraw(); } - environ_tonemap_button->set_pressed(true); - environ_ao_button->set_pressed(false); - environ_gi_button->set_pressed(false); - sun_max_distance->set_value(100); - sun_color->set_pick_color(Color(1, 1, 1)); - sun_energy->set_value(1.0); + if (p_environ) { + environ_sky_color->set_pick_color(GLOBAL_GET("editor/3d/preview_environment/default_sky_color")); + environ_ground_color->set_pick_color(GLOBAL_GET("editor/3d/preview_environment/default_ground_color")); + environ_sky_energy->set_value(GLOBAL_GET("editor/3d/preview_environment/default_sky_energy")); + environ_glow_button->set_pressed(GLOBAL_GET("editor/3d/preview_environment/default_glow") && OS::get_singleton()->get_current_rendering_method() != "gl_compatibility"); + environ_tonemap_button->set_pressed(GLOBAL_GET("editor/3d/preview_environment/default_tonemap")); + environ_ao_button->set_pressed(GLOBAL_GET("editor/3d/preview_environment/default_ao")); + environ_gi_button->set_pressed(GLOBAL_GET("editor/3d/preview_environment/default_gi")); + } sun_environ_updating = false; } @@ -9242,6 +9286,11 @@ Node3DEditor::Node3DEditor() { sun_title->set_text(TTR("Preview Sun")); sun_title->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + sun_revert = memnew(Button); + sun_revert->set_text(TTR("Reset to Default")); + sun_revert->connect(SceneStringName(pressed), callable_mp(this, &Node3DEditor::_revert_preview_sun)); + sun_vb->add_child(sun_revert); + CenterContainer *sun_direction_center = memnew(CenterContainer); sun_direction = memnew(Control); sun_direction->set_custom_minimum_size(Size2(128, 128) * EDSCALE); @@ -9279,7 +9328,7 @@ void fragment() { VBoxContainer *sun_angle_altitude_vbox = memnew(VBoxContainer); sun_angle_altitude_vbox->set_h_size_flags(SIZE_EXPAND_FILL); Label *sun_angle_altitude_label = memnew(Label); - sun_angle_altitude_label->set_text(TTR("Angular Altitude")); + sun_angle_altitude_label->set_text(TTR("Altitude")); sun_angle_altitude_vbox->add_child(sun_angle_altitude_label); sun_angle_altitude = memnew(EditorSpinSlider); sun_angle_altitude->set_suffix(U"\u00B0"); @@ -9321,11 +9370,19 @@ void fragment() { sun_vb->add_margin_child(TTR("Sun Energy"), sun_energy); sun_energy->connect(SceneStringName(value_changed), callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); - sun_max_distance = memnew(EditorSpinSlider); - sun_vb->add_margin_child(TTR("Shadow Max Distance"), sun_max_distance); - sun_max_distance->connect(SceneStringName(value_changed), callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); - sun_max_distance->set_min(1); - sun_max_distance->set_max(4096); + sun_shadow_enabled = memnew(CheckButton); + sun_shadow_enabled->set_text(TTR("Enabled")); + sun_vb->add_margin_child(TTR("Shadow Enabled"), sun_shadow_enabled); + sun_shadow_enabled->connect(SceneStringName(pressed), callable_mp(this, &Node3DEditor::_preview_settings_changed)); + + sun_shadow_max_distance = memnew(EditorSpinSlider); + sun_vb->add_margin_child(TTR("Shadow Max Distance"), sun_shadow_max_distance); + sun_shadow_max_distance->connect(SceneStringName(value_changed), callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + sun_shadow_max_distance->set_min(1.0); + sun_shadow_max_distance->set_max(8192.0); + sun_shadow_max_distance->set_step(0.1); + sun_shadow_max_distance->set_allow_greater(true); + sun_shadow_max_distance->set_exp_ratio(true); sun_add_to_scene = memnew(Button); sun_add_to_scene->set_text(TTR("Add Sun to Scene")); @@ -9357,6 +9414,11 @@ void fragment() { environ_title->set_text(TTR("Preview Environment")); environ_title->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + environ_revert = memnew(Button); + environ_revert->set_text(TTR("Reset to Default")); + environ_revert->connect(SceneStringName(pressed), callable_mp(this, &Node3DEditor::_revert_preview_environ)); + environ_vb->add_child(environ_revert); + environ_sky_color = memnew(ColorPickerButton); environ_sky_color->set_edit_alpha(false); environ_sky_color->connect("color_changed", callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); @@ -9367,12 +9429,12 @@ void fragment() { environ_ground_color->set_edit_alpha(false); environ_ground_color->get_popup()->connect("about_to_popup", callable_mp(EditorNode::get_singleton(), &EditorNode::setup_color_picker).bind(environ_ground_color->get_picker())); environ_vb->add_margin_child(TTR("Ground Color"), environ_ground_color); - environ_energy = memnew(EditorSpinSlider); - environ_energy->set_max(8.0); - environ_energy->set_min(0); - environ_energy->set_step(0.05); - environ_energy->connect(SceneStringName(value_changed), callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); - environ_vb->add_margin_child(TTR("Sky Energy"), environ_energy); + environ_sky_energy = memnew(EditorSpinSlider); + environ_sky_energy->set_max(8.0); + environ_sky_energy->set_min(0); + environ_sky_energy->set_step(0.05); + environ_sky_energy->connect(SceneStringName(value_changed), callable_mp(this, &Node3DEditor::_preview_settings_changed).unbind(1)); + environ_vb->add_margin_child(TTR("Sky Energy"), environ_sky_energy); HBoxContainer *fx_vb = memnew(HBoxContainer); fx_vb->set_h_size_flags(SIZE_EXPAND_FILL); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 27c709fb064..bdf58d8981e 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -42,6 +42,7 @@ class AcceptDialog; class CheckBox; +class CheckButton; class ColorPickerButton; class ConfirmationDialog; class DirectionalLight3D; @@ -845,7 +846,9 @@ private: EditorSpinSlider *sun_angle_azimuth = nullptr; ColorPickerButton *sun_color = nullptr; EditorSpinSlider *sun_energy = nullptr; - EditorSpinSlider *sun_max_distance = nullptr; + CheckButton *sun_shadow_enabled = nullptr; + EditorSpinSlider *sun_shadow_max_distance = nullptr; + Button *sun_revert = nullptr; Button *sun_add_to_scene = nullptr; void _sun_direction_draw(); @@ -863,11 +866,12 @@ private: VBoxContainer *environ_vb = nullptr; ColorPickerButton *environ_sky_color = nullptr; ColorPickerButton *environ_ground_color = nullptr; - EditorSpinSlider *environ_energy = nullptr; + EditorSpinSlider *environ_sky_energy = nullptr; Button *environ_ao_button = nullptr; Button *environ_glow_button = nullptr; Button *environ_tonemap_button = nullptr; Button *environ_gi_button = nullptr; + Button *environ_revert = nullptr; Button *environ_add_to_scene = nullptr; Button *sun_environ_settings = nullptr; @@ -882,20 +886,22 @@ private: bool sun_environ_updating = false; - void _load_default_preview_settings(); + void _load_default_preview_settings(bool p_sun = true, bool p_environ = true); void _update_preview_environment(); void _preview_settings_changed(); void _sun_environ_settings_pressed(); + void _revert_preview_sun(); + void _revert_preview_environ(); void _add_sun_to_scene(bool p_already_added_environment = false); void _add_environment_to_scene(bool p_already_added_sun = false); void _update_theme(); + void _project_settings_changed(); protected: void _notification(int p_what); - //void _gui_input(InputEvent p_event); virtual void shortcut_input(const Ref &p_event) override; static void _bind_methods(); diff --git a/editor/register_editor_types.cpp b/editor/register_editor_types.cpp index 1dfe399a24a..bb25332bfe9 100644 --- a/editor/register_editor_types.cpp +++ b/editor/register_editor_types.cpp @@ -290,6 +290,20 @@ void register_editor_types() { GLOBAL_DEF("editor/version_control/plugin_name", ""); GLOBAL_DEF("editor/version_control/autoload_on_startup", false); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "editor/3d/preview_sun/default_angle_altitude", PROPERTY_HINT_RANGE, "-90,90,0.1,degrees"), 60.0); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "editor/3d/preview_sun/default_angle_azimuth", PROPERTY_HINT_RANGE, "-180,180,0.1,or_greater,or_less,degrees"), 30.0); + GLOBAL_DEF("editor/3d/preview_sun/default_color", Color(1, 1, 1)); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "editor/3d/preview_sun/default_energy", PROPERTY_HINT_RANGE, "0,16,0.001,or_greater"), 1.0); + GLOBAL_DEF("editor/3d/preview_sun/default_shadow_enabled", true); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "editor/3d/preview_sun/default_shadow_max_distance", PROPERTY_HINT_RANGE, "0,8192,0.1,or_greater,exp"), 100.0); + GLOBAL_DEF("editor/3d/preview_environment/default_sky_color", Color(0.385, 0.454, 0.55)); + GLOBAL_DEF("editor/3d/preview_environment/default_ground_color", Color(0.2, 0.169, 0.133)); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "editor/3d/preview_environment/default_sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), 1.0); + GLOBAL_DEF("editor/3d/preview_environment/default_glow", true); + GLOBAL_DEF("editor/3d/preview_environment/default_tonemap", true); + GLOBAL_DEF("editor/3d/preview_environment/default_ao", false); + GLOBAL_DEF("editor/3d/preview_environment/default_gi", false); + EditorInterface::create(); Engine::Singleton ei_singleton = Engine::Singleton("EditorInterface", EditorInterface::get_singleton()); ei_singleton.editor_only = true;