aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp16
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp12
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h2
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp7
-rw-r--r--drivers/gles3/shaders/scene.glsl10
-rw-r--r--drivers/gles3/shaders/subsurf_scattering.glsl4
-rw-r--r--editor/editor_run.cpp8
-rw-r--r--editor/editor_settings.cpp2
-rw-r--r--editor/editor_themes.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp62
-rw-r--r--editor/plugins/script_editor_plugin.h8
-rw-r--r--editor/plugins/script_text_editor.cpp4
-rw-r--r--editor/plugins/script_text_editor.h2
-rw-r--r--editor/project_manager.cpp2
-rw-r--r--editor/property_editor.cpp24
-rw-r--r--editor/scene_tree_dock.cpp62
-rw-r--r--editor/scene_tree_dock.h8
-rw-r--r--modules/hdr/image_loader_hdr.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp4
-rw-r--r--modules/visual_script/visual_script_editor.h1
-rw-r--r--scene/gui/tree.cpp74
-rw-r--r--scene/gui/tree.h13
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/material.cpp161
-rw-r--r--scene/resources/material.h32
-rw-r--r--servers/visual/shader_language.cpp33
-rw-r--r--servers/visual/shader_types.cpp1
27 files changed, 487 insertions, 75 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 5d76a130b..2b0f78e10 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -3028,8 +3028,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
//copy normal and roughness to effect buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT3);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo);
- glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.blur_fbo[0]);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_11_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_LOW);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_17_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_MEDIUM);
@@ -3045,8 +3045,11 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //disable filter (fixes bugs on AMD)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.effect);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[0]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
@@ -3056,10 +3059,15 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
_copy_screen();
glActiveTexture(GL_TEXTURE0);
+
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR, Vector2(0, 1));
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
_copy_screen();
+
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //restore filter
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
if (env->ssr_enabled) {
@@ -3766,7 +3774,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
} else {
- use_mrt = state.used_sss || (env && (env->ssao_enabled || env->ssr_enabled)); //only enable MRT rendering if any of these is enabled
+ use_mrt = env && (state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 1d80e3c42..7ac82a9ec 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -5452,7 +5452,7 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
glDeleteRenderbuffers(1, &rt->buffers.diffuse);
glDeleteRenderbuffers(1, &rt->buffers.specular);
glDeleteRenderbuffers(1, &rt->buffers.normal_rough);
- glDeleteRenderbuffers(1, &rt->buffers.motion_sss);
+ glDeleteRenderbuffers(1, &rt->buffers.sss);
glDeleteFramebuffers(1, &rt->buffers.effect_fbo);
glDeleteTextures(1, &rt->buffers.effect);
@@ -5641,15 +5641,15 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rt->buffers.normal_rough);
- glGenRenderbuffers(1, &rt->buffers.motion_sss);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.motion_sss);
+ glGenRenderbuffers(1, &rt->buffers.sss);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.sss);
if (msaa == 0)
- glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, rt->width, rt->height);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_R8, rt->width, rt->height);
else
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, rt->width, rt->height);
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_R8, rt->width, rt->height);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER, rt->buffers.motion_sss);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER, rt->buffers.sss);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 7e107cfdf..1572d4358 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -1128,7 +1128,7 @@ public:
GLuint specular;
GLuint diffuse;
GLuint normal_rough;
- GLuint motion_sss;
+ GLuint sss;
GLuint effect_fbo;
GLuint effect;
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 7771405bb..5ad2ae736 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -574,6 +574,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions);
} break;
+
default: {
code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions) + ")";
@@ -593,6 +594,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _mktab(p_level) + "else\n";
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions);
}
+ } else if (cfnode->flow_op == SL::FLOW_OP_WHILE) {
+
+ code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ")\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions);
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
@@ -757,7 +762,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
- actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS_MOTION\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index f35e04c5e..29a7135ee 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -523,8 +523,8 @@ uniform int reflection_count;
layout(location=0) out vec4 diffuse_buffer;
layout(location=1) out vec4 specular_buffer;
layout(location=2) out vec4 normal_mr_buffer;
-#if defined (ENABLE_SSS_MOTION)
-layout(location=3) out vec4 motion_ssr_buffer;
+#if defined(ENABLE_SSS)
+layout(location=3) out float sss_buffer;
#endif
#else
@@ -1271,7 +1271,7 @@ void main() {
bool discard_=false;
#endif
-#if defined (ENABLE_SSS_MOTION)
+#if defined (ENABLE_SSS)
float sss_strength=0.0;
#endif
@@ -1616,8 +1616,8 @@ FRAGMENT_SHADER_CODE
normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness);
-#if defined (ENABLE_SSS_MOTION)
- motion_ssr_buffer = vec4(vec3(0.0),sss_strength);
+#if defined (ENABLE_SSS)
+ sss_buffer = sss_strength;
#endif
#else
diff --git a/drivers/gles3/shaders/subsurf_scattering.glsl b/drivers/gles3/shaders/subsurf_scattering.glsl
index eb329dbae..569be6c5f 100644
--- a/drivers/gles3/shaders/subsurf_scattering.glsl
+++ b/drivers/gles3/shaders/subsurf_scattering.glsl
@@ -107,14 +107,14 @@ uniform vec2 dir;
in vec2 uv_interp;
uniform sampler2D source_diffuse; //texunit:0
-uniform sampler2D source_motion_ss; //texunit:1
+uniform sampler2D source_sss; //texunit:1
uniform sampler2D source_depth; //texunit:2
layout(location = 0) out vec4 frag_color;
void main() {
- float strength = texture(source_motion_ss,uv_interp).a;
+ float strength = texture(source_sss,uv_interp).r;
strength*=strength; //stored as sqrt
// Fetch color of current pixel:
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index fea1faec9..c97dc9a88 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -78,12 +78,12 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
Size2 desired_size;
- desired_size.x = GlobalConfig::get_singleton()->get("display/width");
- desired_size.y = GlobalConfig::get_singleton()->get("display/height");
+ desired_size.x = GlobalConfig::get_singleton()->get("display/window/width");
+ desired_size.y = GlobalConfig::get_singleton()->get("display/window/height");
Size2 test_size;
- test_size.x = GlobalConfig::get_singleton()->get("display/test_width");
- test_size.y = GlobalConfig::get_singleton()->get("display/test_height");
+ test_size.x = GlobalConfig::get_singleton()->get("display/window/test_width");
+ test_size.y = GlobalConfig::get_singleton()->get("display/window/test_height");
if (test_size.x > 0 && test_size.y > 0) {
desired_size = test_size;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index df12c7c75..3dab1707a 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -556,6 +556,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("text_editor/line_numbers/line_length_guideline_column", 80);
hints["text_editor/line_numbers/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 10");
+ set("text_editor/open_scripts/show_members_overview", true);
+
set("text_editor/files/trim_trailing_whitespace_on_save", false);
set("text_editor/completion/idle_parse_delay", 2);
set("text_editor/tools/create_signal_callbacks", true);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index bf15f43d3..4e44251f3 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -247,6 +247,10 @@ Ref<Theme> create_editor_theme() {
theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("TreeArrowRight", "EditorIcons"));
theme->set_icon("select_arrow", "Tree", theme->get_icon("Dropdown", "EditorIcons"));
theme->set_stylebox("bg_focus", "Tree", focus_sbt);
+ theme->set_stylebox("custom_button", "Tree", style_button);
+ theme->set_stylebox("custom_button_pressed", "Tree", style_button);
+ theme->set_stylebox("custom_button_hover", "Tree", style_button);
+ theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_LIGHT);
Ref<StyleBox> style_tree_btn = make_flat_stylebox(light_color_1, 2, 4, 2, 4);
theme->set_stylebox("button_pressed", "Tree", style_tree_btn);
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index fde6d83aa..f3941d6a1 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -410,7 +410,9 @@ void ScriptEditor::_go_to_tab(int p_idx) {
c->set_meta("__editor_pass", ++edit_pass);
_update_history_arrows();
_update_script_colors();
+ _update_members_overview();
_update_selected_editor_menu();
+ _update_members_overview_visibility();
}
void ScriptEditor::_add_recent_script(String p_path) {
@@ -540,6 +542,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save) {
_update_history_arrows();
_update_script_names();
+ _update_members_overview_visibility();
_save_layout();
}
@@ -1025,6 +1028,7 @@ void ScriptEditor::_notification(int p_what) {
editor->connect("script_add_function_request", this, "_add_callback");
editor->connect("resource_saved", this, "_res_saved_callback");
script_list->connect("item_selected", this, "_script_selected");
+ members_overview->connect("item_selected", this, "_members_overview_selected");
script_split->connect("dragged", this, "_script_split_dragged");
autosave_timer->connect("timeout", this, "_autosave_scripts");
{
@@ -1273,6 +1277,16 @@ void ScriptEditor::ensure_focus_current() {
se->ensure_focus();
}
+void ScriptEditor::_members_overview_selected(int p_idx) {
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ ScriptEditorBase *se = current->cast_to<ScriptEditorBase>();
+ if (!se) {
+ return;
+ }
+ se->goto_line(members_overview->get_item_metadata(p_idx));
+ se->ensure_focus();
+}
+
void ScriptEditor::_script_selected(int p_idx) {
grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
@@ -1342,6 +1356,37 @@ struct _ScriptEditorItemData {
}
};
+void ScriptEditor::_update_members_overview_visibility() {
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ ScriptEditorBase *se = current->cast_to<ScriptEditorBase>();
+ if (!se) {
+ members_overview->set_visible(false);
+ return;
+ }
+
+ if (members_overview_enabled && se->show_members_overview()) {
+ members_overview->set_visible(true);
+ } else {
+ members_overview->set_visible(false);
+ }
+}
+
+void ScriptEditor::_update_members_overview() {
+ members_overview->clear();
+
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ ScriptEditorBase *se = current->cast_to<ScriptEditorBase>();
+ if (!se) {
+ return;
+ }
+
+ Vector<String> functions = se->get_functions();
+ for (int i = 0; i < functions.size(); i++) {
+ members_overview->add_item(functions[i].get_slice(":", 0));
+ members_overview->set_item_metadata(i, functions[i].get_slice(":", 1).to_int() - 1);
+ }
+}
+
void ScriptEditor::_update_script_colors() {
bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled");
@@ -1485,6 +1530,7 @@ void ScriptEditor::_update_script_names() {
}
}
+ _update_members_overview();
_update_script_colors();
}
@@ -1733,6 +1779,9 @@ void ScriptEditor::_editor_settings_changed() {
convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/indent/convert_indent_on_save");
use_space_indentation = EditorSettings::get_singleton()->get("text_editor/indent/type");
+ members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/show_members_overview");
+ _update_members_overview_visibility();
+
float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs");
if (autosave_time > 0) {
autosave_timer->set_wait_time(autosave_time);
@@ -2084,6 +2133,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_editor_settings_changed", &ScriptEditor::_editor_settings_changed);
ClassDB::bind_method("_update_script_names", &ScriptEditor::_update_script_names);
ClassDB::bind_method("_tree_changed", &ScriptEditor::_tree_changed);
+ ClassDB::bind_method("_members_overview_selected", &ScriptEditor::_members_overview_selected);
ClassDB::bind_method("_script_selected", &ScriptEditor::_script_selected);
ClassDB::bind_method("_script_created", &ScriptEditor::_script_created);
ClassDB::bind_method("_script_split_dragged", &ScriptEditor::_script_split_dragged);
@@ -2105,6 +2155,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
waiting_update_names = false;
pending_auto_reload = false;
auto_reload_running_scripts = false;
+ members_overview_enabled = true;
editor = p_editor;
menu_hb = memnew(HBoxContainer);
@@ -2114,10 +2165,19 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
add_child(script_split);
script_split->set_v_size_flags(SIZE_EXPAND_FILL);
+ list_split = memnew(VSplitContainer);
+ script_split->add_child(list_split);
+ list_split->set_v_size_flags(SIZE_EXPAND_FILL);
+
script_list = memnew(ItemList);
- script_split->add_child(script_list);
+ list_split->add_child(script_list);
script_list->set_custom_minimum_size(Size2(0, 0));
script_split->set_split_offset(140);
+ list_split->set_split_offset(500);
+
+ members_overview = memnew(ItemList);
+ list_split->add_child(members_overview);
+ members_overview->set_custom_minimum_size(Size2(0, 0));
tab_container = memnew(TabContainer);
tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 455a888f0..e036d1ed9 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -102,6 +102,8 @@ public:
virtual void set_debugger_active(bool p_active) = 0;
virtual bool can_lose_focus_on_node_selection() { return true; }
+ virtual bool show_members_overview() = 0;
+
virtual void set_tooltip_request_func(String p_method, Object *p_obj) = 0;
virtual Control *get_edit_menu() = 0;
@@ -179,6 +181,9 @@ class ScriptEditor : public VBoxContainer {
ItemList *script_list;
HSplitContainer *script_split;
+ ItemList *members_overview;
+ bool members_overview_enabled;
+ VSplitContainer *list_split;
TabContainer *tab_container;
EditorFileDialog *file_dialog;
ConfirmationDialog *erase_tab_confirm;
@@ -278,8 +283,11 @@ class ScriptEditor : public VBoxContainer {
void _editor_settings_changed();
void _autosave_scripts();
+ void _update_members_overview_visibility();
+ void _update_members_overview();
void _update_script_names();
+ void _members_overview_selected(int p_idx);
void _script_selected(int p_idx);
void _find_scripts(Node *p_base, Node *p_current, Set<Ref<Script> > &used);
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 70bda3994..9f7611937 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -218,6 +218,10 @@ void ScriptTextEditor::add_callback(const String &p_function, PoolStringArray p_
code_editor->get_text_edit()->cursor_set_column(1);
}
+bool ScriptTextEditor::show_members_overview() {
+ return true;
+}
+
void ScriptTextEditor::update_settings() {
code_editor->update_editor_settings();
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index fdae03949..ba4064516 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -149,6 +149,8 @@ public:
virtual void add_callback(const String &p_function, PoolStringArray p_args);
virtual void update_settings();
+ virtual bool show_members_overview();
+
virtual void set_tooltip_request_func(String p_method, Object *p_obj);
virtual void set_debugger_active(bool p_active);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index a4e8ef70c..4eab20ee7 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1469,7 +1469,7 @@ ProjectListFilter::ProjectListFilter() {
_current_filter = FILTER_NAME;
filter_option = memnew(OptionButton);
- filter_option->set_custom_minimum_size(Size2(80, 10));
+ filter_option->set_custom_minimum_size(Size2(80 * EDSCALE, 10 * EDSCALE));
filter_option->set_clip_text(true);
filter_option->connect("item_selected", this, "_filter_option_selected");
add_child(filter_option);
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 5ae6cf300..d1b79ea7a 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -2310,6 +2310,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p
if (obj->get(p_name).get_type() == Variant::NIL || obj->get(p_name).operator RefPtr().is_null()) {
p_item->set_text(1, "<null>");
p_item->set_icon(1, Ref<Texture>());
+ p_item->set_custom_as_button(1, false);
Dictionary d = p_item->get_metadata(0);
int hint = d.has("hint") ? d["hint"].operator int() : -1;
@@ -2319,6 +2320,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p
}
} else {
+ p_item->set_custom_as_button(1, true);
RES res = obj->get(p_name).operator RefPtr();
if (res->is_class("Texture")) {
int tw = EditorSettings::get_singleton()->get("docks/property_editor/texture_preview_width");
@@ -3540,17 +3542,21 @@ void PropertyEditor::update_tree() {
item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM);
item->set_editable(1, !read_only);
- item->add_button(1, get_icon("EditResource", "EditorIcons"));
+ //item->add_button(1, get_icon("EditResource", "EditorIcons"));
String type;
if (p.hint == PROPERTY_HINT_RESOURCE_TYPE)
type = p.hint_string;
- if (obj->get(p.name).get_type() == Variant::NIL || obj->get(p.name).operator RefPtr().is_null()) {
+ RES res = obj->get(p.name).operator RefPtr();
+
+ if (obj->get(p.name).get_type() == Variant::NIL || res.is_null()) {
item->set_text(1, "<null>");
item->set_icon(1, Ref<Texture>());
+ item->set_custom_as_button(1, false);
- } else {
- RES res = obj->get(p.name).operator RefPtr();
+ } else if (res.is_valid()) {
+
+ item->set_custom_as_button(1, true);
if (res->is_class("Texture")) {
int tw = EditorSettings::get_singleton()->get("docks/property_editor/texture_preview_width");
@@ -3854,6 +3860,16 @@ void PropertyEditor::_item_edited() {
_edit_set(name, NodePath(item->get_text(1)), refresh_all);
} break;
+ case Variant::OBJECT: {
+ if (!item->is_custom_set_as_button(1))
+ break;
+
+ RES res = obj->get(name);
+ if (res.is_valid()) {
+ emit_signal("resource_selected", res.get_ref_ptr(), name);
+ }
+
+ } break;
case Variant::DICTIONARY: {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 0f05cc79f..da2d22b90 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -658,6 +658,21 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
} break;
+
+ default: {
+
+ if (p_tool >= EDIT_SUBRESOURCE_BASE) {
+
+ int idx = p_tool - EDIT_SUBRESOURCE_BASE;
+
+ ERR_FAIL_INDEX(idx, subresources.size());
+
+ Object *obj = ObjectDB::get_instance(subresources[idx]);
+ ERR_FAIL_COND(!obj);
+
+ editor->push_item(obj);
+ }
+ }
}
}
@@ -1662,6 +1677,47 @@ void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
_do_reparent(to_node, to_pos, nodes, true);
}
+void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) {
+
+ if (p_depth > 8)
+ return;
+
+ List<PropertyInfo> pinfo;
+ p_obj->get_property_list(&pinfo);
+ for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
+
+ if (!(E->get().usage & PROPERTY_USAGE_EDITOR))
+ continue;
+ if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE)
+ continue;
+
+ Variant value = p_obj->get(E->get().name);
+ if (value.get_type() != Variant::OBJECT)
+ continue;
+ Object *obj = value;
+ if (!obj)
+ continue;
+
+ Ref<Texture> icon;
+
+ if (has_icon(obj->get_class(), "EditorIcons"))
+ icon = get_icon(obj->get_class(), "EditorIcons");
+ else
+ icon = get_icon("Object", "EditorIcons");
+
+ if (menu->get_item_count() == 0) {
+ menu->add_item(TTR("Sub-Resources:"));
+ menu->set_item_disabled(0, true);
+ }
+ int index = menu->get_item_count();
+ menu->add_icon_item(icon, E->get().name.capitalize(), EDIT_SUBRESOURCE_BASE + subresources.size());
+ menu->set_item_h_offset(index, p_depth * 10 * EDSCALE);
+ subresources.push_back(obj->get_instance_ID());
+
+ _add_children_to_popup(obj, p_depth + 1);
+ }
+}
+
void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (!EditorNode::get_singleton()->get_edited_scene()) {
@@ -1683,6 +1739,12 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->clear();
if (selection.size() == 1) {
+
+ subresources.clear();
+ _add_children_to_popup(selection.front()->get(), 0);
+ if (menu->get_item_count() > 0)
+ menu->add_separator();
+
menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
menu->add_separator();
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index f190025dd..79e01e757 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -73,6 +73,12 @@ class SceneTreeDock : public VBoxContainer {
TOOL_BUTTON_MAX
};
+ enum {
+ EDIT_SUBRESOURCE_BASE = 100
+ };
+
+ Vector<ObjectID> subresources;
+
bool restore_script_editor_on_drag;
int current_option;
@@ -114,6 +120,8 @@ class SceneTreeDock : public VBoxContainer {
Node *edited_scene;
EditorNode *editor;
+ void _add_children_to_popup(Object *p_obj, int p_depth);
+
Node *_duplicate(Node *p_node, Map<Node *, Node *> &duplimap);
void _node_reparent(NodePath p_path, bool p_keep_global_xform);
void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform);
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index 85819104c..19df27b96 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -131,7 +131,7 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
//convert
for (int i = 0; i < width * height; i++) {
- float exp = pow(2, ptr[3] - 128);
+ float exp = pow(2.0f, ptr[3] - 128.0f);
Color c(
ptr[0] * exp / 255.0,
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index b68f8f1f0..941668d47 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -2240,6 +2240,10 @@ void VisualScriptEditor::add_callback(const String &p_function, PoolStringArray
//undo_redo->clear_history();
}
+bool VisualScriptEditor::show_members_overview() {
+ return false;
+}
+
void VisualScriptEditor::update_settings() {
_update_graph();
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index bb832431a..92f31f20d 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -248,6 +248,7 @@ public:
virtual void get_breakpoints(List<int> *p_breakpoints);
virtual void add_callback(const String &p_function, PoolStringArray p_args);
virtual void update_settings();
+ virtual bool show_members_overview();
virtual void set_debugger_active(bool p_active);
virtual void set_tooltip_request_func(String p_method, Object *p_obj);
virtual Control *get_edit_menu();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 6ea3ee001..7d0b8757c 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -610,6 +610,18 @@ Color TreeItem::get_custom_bg_color(int p_column) const {
return cells[p_column].bg_color;
}
+void TreeItem::set_custom_as_button(int p_column, bool p_button) {
+
+ ERR_FAIL_INDEX(p_column, cells.size());
+ cells[p_column].custom_button = p_button;
+}
+
+bool TreeItem::is_custom_set_as_button(int p_column) const {
+
+ ERR_FAIL_INDEX_V(p_column, cells.size(), false);
+ return cells[p_column].custom_button;
+}
+
void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cell_mode", "column", "mode"), &TreeItem::set_cell_mode);
@@ -670,6 +682,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_custom_bg_color", "column"), &TreeItem::clear_custom_bg_color);
ClassDB::bind_method(D_METHOD("get_custom_bg_color", "column"), &TreeItem::get_custom_bg_color);
+ ClassDB::bind_method(D_METHOD("set_custom_as_button", "column", "enable"), &TreeItem::set_custom_as_button);
+ ClassDB::bind_method(D_METHOD("is_custom_set_as_button", "column"), &TreeItem::is_custom_set_as_button);
+
ClassDB::bind_method(D_METHOD("add_button", "column", "button:Texture", "button_idx", "disabled", "tooltip"), &TreeItem::add_button, DEFVAL(-1), DEFVAL(false), DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_button_count", "column"), &TreeItem::get_button_count);
ClassDB::bind_method(D_METHOD("get_button:Texture", "column", "button_idx"), &TreeItem::get_button);
@@ -732,6 +747,10 @@ TreeItem::~TreeItem() {
tree->pressing_for_editor = false;
}
+ if (tree && tree->cache.hover_item == this) {
+ tree->cache.hover_item = NULL;
+ }
+
if (tree && tree->selected_item == this)
tree->selected_item = NULL;
@@ -772,6 +791,11 @@ void Tree::update_cache() {
cache.select_arrow = get_icon("select_arrow");
cache.updown = get_icon("updown");
+ cache.custom_button = get_stylebox("custom_button");
+ cache.custom_button_hover = get_stylebox("custom_button_hover");
+ cache.custom_button_pressed = get_stylebox("custom_button_pressed");
+ cache.custom_button_font_highlight = get_color("custom_button_font_highlight");
+
cache.font_color = get_color("font_color");
cache.font_color_selected = get_color("font_color_selected");
cache.guide_color = get_color("guide_color");
@@ -833,6 +857,9 @@ int Tree::compute_item_height(TreeItem *p_item) const {
if (s.height > height)
height = s.height;
}
+ if (p_item->cells[i].mode == TreeItem::CELL_MODE_CUSTOM && p_item->cells[i].custom_button) {
+ height += cache.custom_button->get_minimum_size().height;
+ }
} break;
default: {}
@@ -1202,12 +1229,28 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
Ref<Texture> downarrow = cache.select_arrow;
Rect2i ir = item_rect;
- ir.size.width -= downarrow->get_width();
- draw_item_rect(p_item->cells[i], ir, col);
Point2i arrow_pos = item_rect.position;
arrow_pos.x += item_rect.size.x - downarrow->get_width();
arrow_pos.y += Math::floor(((item_rect.size.y - downarrow->get_height())) / 2.0);
+ ir.size.width -= downarrow->get_width();
+
+ if (p_item->cells[i].custom_button) {
+ if (cache.hover_item == p_item && cache.hover_cell == i) {
+ if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+ draw_style_box(cache.custom_button_pressed, ir);
+ } else {
+ draw_style_box(cache.custom_button_hover, ir);
+ col = cache.custom_button_font_highlight;
+ }
+ } else {
+ draw_style_box(cache.custom_button, ir);
+ }
+ ir.size -= cache.custom_button->get_minimum_size();
+ ir.pos += cache.custom_button->get_offset();
+ }
+
+ draw_item_rect(p_item->cells[i], ir, col);
downarrow->draw(ci, arrow_pos);
@@ -1697,11 +1740,18 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
case TreeItem::CELL_MODE_CUSTOM: {
edited_item = p_item;
edited_col = col;
- custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h));
- emit_signal("custom_popup_edited", ((bool)(x >= (col_width - item_h / 2))));
+ bool on_arrow = x > col_width - cache.select_arrow->get_width();
bring_up_editor = false;
- item_edited(col, p_item);
+
+ if (on_arrow || !p_item->cells[col].custom_button) {
+ custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h));
+ emit_signal("custom_popup_edited", ((bool)(x >= (col_width - item_h / 2))));
+ }
+
+ if (!p_item->cells[col].custom_button || !on_arrow) {
+ item_edited(col, p_item);
+ }
click_handled = true;
return -1;
} break;
@@ -2148,7 +2198,7 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
}
- if (drop_mode_flags && root) {
+ if (root) {
Point2 mpos = mm->get_position();
mpos -= cache.bg->get_offset();
@@ -2163,11 +2213,17 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
int col, h, section;
TreeItem *it = _find_item_at_pos(root, mpos, col, h, section);
- if (it != drop_mode_over || section != drop_mode_section) {
+ if (drop_mode_flags && it != drop_mode_over || section != drop_mode_section) {
drop_mode_over = it;
drop_mode_section = section;
update();
}
+
+ if (it != cache.hover_item || col != cache.hover_cell) {
+ cache.hover_item = it;
+ cache.hover_cell = col;
+ update();
+ }
}
}
@@ -3469,6 +3525,7 @@ void Tree::_bind_methods() {
ADD_SIGNAL(MethodInfo("item_rmb_selected", PropertyInfo(Variant::VECTOR2, "pos")));
ADD_SIGNAL(MethodInfo("empty_tree_rmb_selected", PropertyInfo(Variant::VECTOR2, "pos")));
ADD_SIGNAL(MethodInfo("item_edited"));
+ ADD_SIGNAL(MethodInfo("item_custom_button_pressed"));
ADD_SIGNAL(MethodInfo("item_double_clicked"));
ADD_SIGNAL(MethodInfo("item_collapsed", PropertyInfo(Variant::OBJECT, "item")));
//ADD_SIGNAL( MethodInfo("item_doubleclicked" ) );
@@ -3575,6 +3632,9 @@ Tree::Tree() {
force_edit_checkbox_only_on_checkbox = false;
set_clip_contents(true);
+
+ cache.hover_item = NULL;
+ cache.hover_cell = -1;
}
Tree::~Tree() {
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 0c07109e7..097e0110e 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -81,6 +81,7 @@ private:
bool custom_bg_color;
bool custom_bg_outline;
Color bg_color;
+ bool custom_button;
Variant meta;
String tooltip;
@@ -107,6 +108,7 @@ private:
Cell() {
custom_draw_obj = 0;
+ custom_button = false;
mode = TreeItem::CELL_MODE_STRING;
min = 0;
max = 100;
@@ -238,6 +240,9 @@ public:
void clear_custom_bg_color(int p_column);
Color get_custom_bg_color(int p_column) const;
+ void set_custom_as_button(int p_column, bool p_button);
+ bool is_custom_set_as_button(int p_column) const;
+
void set_tooltip(int p_column, const String &p_tooltip);
String get_tooltip(int p_column) const;
@@ -369,6 +374,10 @@ private:
Ref<StyleBox> title_button;
Ref<StyleBox> title_button_hover;
Ref<StyleBox> title_button_pressed;
+ Ref<StyleBox> custom_button;
+ Ref<StyleBox> custom_button_hover;
+ Ref<StyleBox> custom_button_pressed;
+
Color title_button_color;
Ref<Texture> checked;
@@ -383,6 +392,7 @@ private:
Color guide_color;
Color drop_position_color;
Color relationship_line_color;
+ Color custom_button_font_highlight;
int hseparation;
int vseparation;
@@ -410,6 +420,9 @@ private:
int hover_index;
Point2 click_pos;
+ TreeItem *hover_item;
+ int hover_cell;
+
} cache;
int _get_title_button_height() const;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index fa2418f6b..668a8ff66 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -626,6 +626,9 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_stylebox("title_button_normal", "Tree", make_stylebox(tree_title_png, 4, 4, 4, 4));
t->set_stylebox("title_button_pressed", "Tree", make_stylebox(tree_title_pressed_png, 4, 4, 4, 4));
t->set_stylebox("title_button_hover", "Tree", make_stylebox(tree_title_png, 4, 4, 4, 4));
+ t->set_stylebox("custom_button", "Tree", sb_button_normal);
+ t->set_stylebox("custom_button_pressed", "Tree", sb_button_pressed);
+ t->set_stylebox("custom_button_hover", "Tree", sb_button_hover);
t->set_icon("checked", "Tree", make_icon(checked_png));
t->set_icon("unchecked", "Tree", make_icon(unchecked_png));
@@ -645,6 +648,7 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1));
t->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2));
t->set_color("relationship_line_color", "Tree", Color::html("464646"));
+ t->set_color("custom_button_font_highlight", "Tree", control_font_color_hover);
t->set_constant("hseparation", "Tree", 4 * scale);
t->set_constant("vseparation", "Tree", 4 * scale);
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 026b243b2..a9205fd57 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -190,7 +190,7 @@ void SpatialMaterial::init_shaders() {
shader_names->clearcoat = "clearcoat";
shader_names->clearcoat_gloss = "clearcoat_gloss";
shader_names->anisotropy = "anisotropy_ratio";
- shader_names->height_scale = "height_scale";
+ shader_names->depth_scale = "depth_scale";
shader_names->subsurface_scattering_strength = "subsurface_scattering_strength";
shader_names->refraction = "refraction";
shader_names->refraction_roughness = "refraction_roughness";
@@ -203,6 +203,8 @@ void SpatialMaterial::init_shaders() {
shader_names->particle_h_frames = "particle_h_frames";
shader_names->particle_v_frames = "particle_v_frames";
shader_names->particles_anim_loop = "particles_anim_loop";
+ shader_names->depth_min_layers = "depth_min_layers";
+ shader_names->depth_max_layers = "depth_max_layers";
shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo";
shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic";
@@ -213,7 +215,7 @@ void SpatialMaterial::init_shaders() {
shader_names->texture_names[TEXTURE_CLEARCOAT] = "texture_clearcoat";
shader_names->texture_names[TEXTURE_FLOWMAP] = "texture_flowmap";
shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion";
- shader_names->texture_names[TEXTURE_HEIGHT] = "texture_height";
+ shader_names->texture_names[TEXTURE_DEPTH] = "texture_depth";
shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering";
shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction";
shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask";
@@ -354,6 +356,13 @@ void SpatialMaterial::_update_shader() {
code += "uniform sampler2D texture_subsurface_scattering : hint_white;\n";
}
+ if (features[FEATURE_DEPTH_MAPPING]) {
+ code += "uniform sampler2D texture_depth : hint_black;\n";
+ code += "uniform float depth_scale;\n";
+ code += "uniform int depth_min_layers;\n";
+ code += "uniform int depth_max_layers;\n";
+ }
+
code += "\n\n";
code += "void vertex() {\n";
@@ -427,10 +436,52 @@ void SpatialMaterial::_update_shader() {
code += "\n\n";
code += "void fragment() {\n";
+ code += "\tvec2 base_uv = UV;\n";
+ if (features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) {
+ code += "\tvec2 base_uv2 = UV2;\n";
+ }
+
+ if (features[FEATURE_DEPTH_MAPPING]) {
+ code += "\t{\n";
+ code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT,BINORMAL,NORMAL));\n";
+
+ if (deep_parallax) {
+ code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
+ code += "\t\tfloat layer_depth = 1.0 / num_layers;\n";
+ code += "\t\tfloat current_layer_depth = 0.0;\n";
+ code += "\t\tvec2 P = view_dir.xy * depth_scale;\n";
+ code += "\t\tvec2 delta = P / num_layers;\n";
+ code += "\t\tvec2 ofs = base_uv;\n";
+ code += "\t\tfloat depth = texture(texture_depth, ofs).r;\n";
+ code += "\t\tfloat current_depth = 0.0;\n";
+ code += "\t\twhile(current_depth < depth) {\n";
+ code += "\t\t\tofs -= delta;\n";
+ code += "\t\t\tdepth = texture(texture_depth, ofs).r;\n";
+ code += "\t\t\tcurrent_depth += layer_depth;\n";
+ code += "\t\t}\n";
+ code += "\t\tvec2 prev_ofs = ofs + delta;\n";
+ code += "\t\tfloat after_depth = depth - current_depth;\n";
+ code += "\t\tfloat before_depth = texture(texture_depth, prev_ofs).r - current_depth + layer_depth;\n";
+ code += "\t\tfloat weight = after_depth / (after_depth - before_depth);\n";
+ code += "\t\tofs = mix(ofs,prev_ofs,weight);\n";
+
+ } else {
+ code += "\t\tfloat depth = texture(texture_depth, base_uv).r;\n";
+ code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * depth_scale);\n";
+ }
+
+ code += "\t\tbase_uv=ofs;\n";
+ if (features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) {
+ code += "\t\tbase_uv2-=ofs;\n";
+ }
+
+ code += "\t}\n";
+ }
+
if (flags[FLAG_USE_POINT_SIZE]) {
code += "\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
} else {
- code += "\tvec4 albedo_tex = texture(texture_albedo,UV);\n";
+ code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
}
if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
@@ -443,47 +494,47 @@ void SpatialMaterial::_update_shader() {
}
if (features[FEATURE_EMISSION]) {
- code += "\tEMISSION = (emission.rgb+texture(texture_emission,UV).rgb)*emission_energy;\n";
+ code += "\tEMISSION = (emission.rgb+texture(texture_emission,base_uv).rgb)*emission_energy;\n";
}
if (features[FEATURE_NORMAL_MAPPING]) {
- code += "\tNORMALMAP = texture(texture_normal,UV).rgb;\n";
+ code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n";
code += "\tNORMALMAP_DEPTH = normal_scale;\n";
}
if (features[FEATURE_RIM]) {
- code += "\tvec2 rim_tex = texture(texture_rim,UV).xw;\n";
+ code += "\tvec2 rim_tex = texture(texture_rim,base_uv).xw;\n";
code += "\tRIM = rim*rim_tex.x;";
code += "\tRIM_TINT = rim_tint*rim_tex.y;\n";
}
if (features[FEATURE_CLEARCOAT]) {
- code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,UV).xw;\n";
+ code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xw;\n";
code += "\tCLEARCOAT = clearcoat*clearcoat_tex.x;";
code += "\tCLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n";
}
if (features[FEATURE_ANISOTROPY]) {
- code += "\tvec4 anisotropy_tex = texture(texture_flowmap,UV);\n";
+ code += "\tvec4 anisotropy_tex = texture(texture_flowmap,base_uv);\n";
code += "\tANISOTROPY = anisotropy_ratio*anisotropy_tex.a;\n";
code += "\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n";
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
- code += "\tAO = texture(texture_ambient_occlusion,UV).r;\n";
+ code += "\tAO = texture(texture_ambient_occlusion,base_uv).r;\n";
}
if (features[FEATURE_SUBSURACE_SCATTERING]) {
- code += "\tfloat sss_tex = texture(texture_subsurface_scattering,UV).r;\n";
+ code += "\tfloat sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n";
code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
}
if (features[FEATURE_DETAIL]) {
- String det_uv = detail_uv == DETAIL_UV_1 ? "UV" : "UV2";
+ String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2";
code += "\tvec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n";
code += "\tvec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n";
- code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,UV);\n";
+ code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
switch (detail_blend_mode) {
case BLEND_MODE_MIX: {
@@ -506,9 +557,9 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
}
- code += "\tfloat metallic_tex = texture(texture_metallic,UV).r;\n";
+ code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n";
code += "\tMETALLIC = metallic_tex * metallic;\n";
- code += "\tfloat roughness_tex = texture(texture_roughness,UV).r;\n";
+ code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n";
code += "\tROUGHNESS = roughness_tex * roughness;\n";
code += "\tSPECULAR = specular;\n";
@@ -693,15 +744,15 @@ float SpatialMaterial::get_anisotropy() const {
return anisotropy;
}
-void SpatialMaterial::set_height_scale(float p_height_scale) {
+void SpatialMaterial::set_depth_scale(float p_depth_scale) {
- height_scale = p_height_scale;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->height_scale, p_height_scale);
+ depth_scale = p_depth_scale;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_scale, p_depth_scale);
}
-float SpatialMaterial::get_height_scale() const {
+float SpatialMaterial::get_depth_scale() const {
- return height_scale;
+ return depth_scale;
}
void SpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
@@ -863,6 +914,9 @@ void SpatialMaterial::_validate_feature(const String &text, Feature feature, Pro
if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) {
property.usage = 0;
}
+ if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) {
+ property.usage = 0;
+ }
}
void SpatialMaterial::_validate_property(PropertyInfo &property) const {
@@ -872,7 +926,7 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
_validate_feature("clearcoat", FEATURE_CLEARCOAT, property);
_validate_feature("anisotropy", FEATURE_ANISOTROPY, property);
_validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property);
- _validate_feature("height", FEATURE_HEIGHT_MAPPING, property);
+ _validate_feature("depth", FEATURE_DEPTH_MAPPING, property);
_validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property);
_validate_feature("refraction", FEATURE_REFRACTION, property);
_validate_feature("detail", FEATURE_DETAIL, property);
@@ -991,6 +1045,39 @@ int SpatialMaterial::get_particles_anim_loop() const {
return particles_anim_loop;
}
+void SpatialMaterial::set_depth_deep_parallax(bool p_enable) {
+
+ deep_parallax = p_enable;
+ _queue_shader_change();
+ _change_notify();
+ ;
+}
+
+bool SpatialMaterial::is_depth_deep_parallax_enabled() const {
+
+ return deep_parallax;
+}
+
+void SpatialMaterial::set_depth_deep_parallax_min_layers(int p_layer) {
+
+ deep_parallax_min_layers = p_layer;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_min_layers, p_layer);
+}
+int SpatialMaterial::get_depth_deep_parallax_min_layers() const {
+
+ return deep_parallax_min_layers;
+}
+
+void SpatialMaterial::set_depth_deep_parallax_max_layers(int p_layer) {
+
+ deep_parallax_max_layers = p_layer;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_max_layers, p_layer);
+}
+int SpatialMaterial::get_depth_deep_parallax_max_layers() const {
+
+ return deep_parallax_max_layers;
+}
+
void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
@@ -1029,8 +1116,8 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &SpatialMaterial::set_anisotropy);
ClassDB::bind_method(D_METHOD("get_anisotropy"), &SpatialMaterial::get_anisotropy);
- ClassDB::bind_method(D_METHOD("set_height_scale", "height_scale"), &SpatialMaterial::set_height_scale);
- ClassDB::bind_method(D_METHOD("get_height_scale"), &SpatialMaterial::get_height_scale);
+ ClassDB::bind_method(D_METHOD("set_depth_scale", "depth_scale"), &SpatialMaterial::set_depth_scale);
+ ClassDB::bind_method(D_METHOD("get_depth_scale"), &SpatialMaterial::get_depth_scale);
ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &SpatialMaterial::set_subsurface_scattering_strength);
ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &SpatialMaterial::get_subsurface_scattering_strength);
@@ -1098,6 +1185,15 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "frames"), &SpatialMaterial::set_particles_anim_loop);
ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &SpatialMaterial::get_particles_anim_loop);
+ ClassDB::bind_method(D_METHOD("set_depth_deep_parallax", "enable"), &SpatialMaterial::set_depth_deep_parallax);
+ ClassDB::bind_method(D_METHOD("is_depth_deep_parallax_enabled"), &SpatialMaterial::is_depth_deep_parallax_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_min_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_min_layers);
+ ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_min_layers"), &SpatialMaterial::get_depth_deep_parallax_min_layers);
+
+ ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_max_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_max_layers);
+ ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_max_layers"), &SpatialMaterial::get_depth_deep_parallax_max_layers);
+
ADD_GROUP("Flags", "flags_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
@@ -1166,10 +1262,13 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled"), "set_feature", "get_feature", FEATURE_AMBIENT_OCCLUSION);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
- ADD_GROUP("Height", "height_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "height_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_height_scale", "get_height_scale");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "height_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_HEIGHT);
+ ADD_GROUP("Depth", "depth_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "depth_enabled"), "set_feature", "get_feature", FEATURE_DEPTH_MAPPING);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_depth_scale", "get_depth_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_deep_parallax"), "set_depth_deep_parallax", "is_depth_deep_parallax_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_min_layers", "get_depth_deep_parallax_min_layers");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_max_layers", "get_depth_deep_parallax_max_layers");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "depth_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DEPTH);
ADD_GROUP("Subsurf Scatter", "subsurf_scatter_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURACE_SCATTERING);
@@ -1207,7 +1306,7 @@ void SpatialMaterial::_bind_methods() {
BIND_CONSTANT(TEXTURE_CLEARCOAT);
BIND_CONSTANT(TEXTURE_FLOWMAP);
BIND_CONSTANT(TEXTURE_AMBIENT_OCCLUSION);
- BIND_CONSTANT(TEXTURE_HEIGHT);
+ BIND_CONSTANT(TEXTURE_DEPTH);
BIND_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING);
BIND_CONSTANT(TEXTURE_REFRACTION);
BIND_CONSTANT(TEXTURE_DETAIL_MASK);
@@ -1225,7 +1324,7 @@ void SpatialMaterial::_bind_methods() {
BIND_CONSTANT(FEATURE_CLEARCOAT);
BIND_CONSTANT(FEATURE_ANISOTROPY);
BIND_CONSTANT(FEATURE_AMBIENT_OCCLUSION);
- BIND_CONSTANT(FEATURE_HEIGHT_MAPPING);
+ BIND_CONSTANT(FEATURE_DEPTH_MAPPING);
BIND_CONSTANT(FEATURE_SUBSURACE_SCATTERING);
BIND_CONSTANT(FEATURE_REFRACTION);
BIND_CONSTANT(FEATURE_DETAIL);
@@ -1280,7 +1379,7 @@ SpatialMaterial::SpatialMaterial()
set_clearcoat(1);
set_clearcoat_gloss(0.5);
set_anisotropy(0);
- set_height_scale(1);
+ set_depth_scale(0.05);
set_subsurface_scattering_strength(0);
set_refraction(0);
set_refraction_roughness(0);
@@ -1295,6 +1394,10 @@ SpatialMaterial::SpatialMaterial()
set_particles_anim_v_frames(1);
set_particles_anim_loop(false);
+ deep_parallax = false;
+ set_depth_deep_parallax_min_layers(8);
+ set_depth_deep_parallax_max_layers(32);
+
detail_uv = DETAIL_UV_1;
blend_mode = BLEND_MODE_MIX;
detail_blend_mode = BLEND_MODE_MIX;
diff --git a/scene/resources/material.h b/scene/resources/material.h
index f4d93da01..e72d3d455 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -97,7 +97,7 @@ public:
TEXTURE_CLEARCOAT,
TEXTURE_FLOWMAP,
TEXTURE_AMBIENT_OCCLUSION,
- TEXTURE_HEIGHT,
+ TEXTURE_DEPTH,
TEXTURE_SUBSURFACE_SCATTERING,
TEXTURE_REFRACTION,
TEXTURE_DETAIL_MASK,
@@ -120,7 +120,7 @@ public:
FEATURE_CLEARCOAT,
FEATURE_ANISOTROPY,
FEATURE_AMBIENT_OCCLUSION,
- FEATURE_HEIGHT_MAPPING,
+ FEATURE_DEPTH_MAPPING,
FEATURE_SUBSURACE_SCATTERING,
FEATURE_REFRACTION,
FEATURE_DETAIL,
@@ -185,7 +185,7 @@ private:
uint32_t detail_blend_mode : 2;
uint32_t diffuse_mode : 2;
uint32_t invalid_key : 1;
- uint32_t specular_mode : 1;
+ uint32_t deep_parallax : 1;
uint32_t billboard_mode : 2;
};
@@ -226,6 +226,8 @@ private:
mk.detail_blend_mode = detail_blend_mode;
mk.diffuse_mode = diffuse_mode;
mk.billboard_mode = billboard_mode;
+ mk.deep_parallax = deep_parallax ? 1 : 0;
+ ;
return mk;
}
@@ -243,7 +245,7 @@ private:
StringName clearcoat;
StringName clearcoat_gloss;
StringName anisotropy;
- StringName height_scale;
+ StringName depth_scale;
StringName subsurface_scattering_strength;
StringName refraction;
StringName refraction_roughness;
@@ -255,6 +257,9 @@ private:
StringName particle_h_frames;
StringName particle_v_frames;
StringName particles_anim_loop;
+ StringName depth_min_layers;
+ StringName depth_max_layers;
+
StringName texture_names[TEXTURE_MAX];
};
@@ -280,7 +285,7 @@ private:
float clearcoat;
float clearcoat_gloss;
float anisotropy;
- float height_scale;
+ float depth_scale;
float subsurface_scattering_strength;
float refraction;
float refraction_roughness;
@@ -298,6 +303,10 @@ private:
DetailUV detail_uv;
+ bool deep_parallax;
+ int deep_parallax_min_layers;
+ int deep_parallax_max_layers;
+
BlendMode blend_mode;
BlendMode detail_blend_mode;
DepthDrawMode depth_draw_mode;
@@ -353,8 +362,17 @@ public:
void set_anisotropy(float p_anisotropy);
float get_anisotropy() const;
- void set_height_scale(float p_height_scale);
- float get_height_scale() const;
+ void set_depth_scale(float p_depth_scale);
+ float get_depth_scale() const;
+
+ void set_depth_deep_parallax(bool p_enable);
+ bool is_depth_deep_parallax_enabled() const;
+
+ void set_depth_deep_parallax_min_layers(int p_layer);
+ int get_depth_deep_parallax_min_layers() const;
+
+ void set_depth_deep_parallax_max_layers(int p_layer);
+ int get_depth_deep_parallax_max_layers() const;
void set_subsurface_scattering_strength(float p_strength);
float get_subsurface_scattering_strength() const;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 9fe92f0fe..319351f8e 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -3185,7 +3185,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected '(' after expression");
+ _set_error("Expected ')' after expression");
return ERR_PARSE_ERROR;
}
@@ -3196,6 +3196,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
p_block->statements.push_back(cf);
Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ if (err)
+ return err;
pos = _get_tkpos();
tk = _get_token();
@@ -3209,6 +3211,35 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
} else {
_set_tkpos(pos); //rollback
}
+ } else if (tk.type == TK_CF_WHILE) {
+ //if () {}
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after if");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ cf->flow_op = FLOW_OP_WHILE;
+ Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
+
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' after expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ BlockNode *block = alloc_node<BlockNode>();
+ block->parent_block = p_block;
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(block);
+ p_block->statements.push_back(cf);
+
+ Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ if (err)
+ return err;
} else if (tk.type == TK_CF_RETURN) {
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 1caee3fd2..ea012f195 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -52,7 +52,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_TANGENT"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_BONES"] = ShaderLanguage::TYPE_IVEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;