summaryrefslogtreecommitdiffstats
path: root/scene/resources/material.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources/material.cpp')
-rw-r--r--scene/resources/material.cpp58
1 files changed, 29 insertions, 29 deletions
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 15b40e776c..8e49a8b56f 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -35,7 +35,6 @@
#include "core/error/error_macros.h"
#include "core/version.h"
#include "scene/main/scene_tree.h"
-#include "scene/scene_string_names.h"
void Material::set_next_pass(const Ref<Material> &p_pass) {
for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) {
@@ -82,24 +81,25 @@ void Material::_validate_property(PropertyInfo &p_property) const {
}
}
-void Material::_mark_initialized(const Callable &p_queue_shader_change_callable) {
+void Material::_mark_ready() {
+ init_state = INIT_STATE_INITIALIZING;
+}
+
+void Material::_mark_initialized(const Callable &p_add_to_dirty_list, const Callable &p_update_shader) {
// If this is happening as part of resource loading, it is not safe to queue the update
- // as an addition to the dirty list, unless the load is happening on the main thread.
- if (ResourceLoader::is_within_load() && Thread::get_caller_id() != Thread::get_main_id()) {
+ // as an addition to the dirty list. It would be if the load is happening on the main thread,
+ // but even so we'd rather perform the update directly instead of using the dirty list.
+ if (ResourceLoader::is_within_load()) {
DEV_ASSERT(init_state != INIT_STATE_READY);
if (init_state == INIT_STATE_UNINITIALIZED) { // Prevent queueing twice.
- // Let's mark this material as being initialized.
init_state = INIT_STATE_INITIALIZING;
- // Knowing that the ResourceLoader will eventually feed deferred calls into the main message queue, let's do these:
- // 1. Queue setting the init state to INIT_STATE_READY finally.
- callable_mp(this, &Material::_mark_initialized).bind(p_queue_shader_change_callable).call_deferred();
- // 2. Queue an individual update of this material.
- p_queue_shader_change_callable.call_deferred();
+ callable_mp(this, &Material::_mark_ready).call_deferred();
+ p_update_shader.call_deferred();
}
} else {
// Straightforward conditions.
init_state = INIT_STATE_READY;
- p_queue_shader_change_callable.callv(Array());
+ p_add_to_dirty_list.call();
}
}
@@ -603,8 +603,6 @@ void BaseMaterial3D::finish_shaders() {
}
void BaseMaterial3D::_update_shader() {
- dirty_materials.remove(&element);
-
MaterialKey mk = _compute_key();
if (mk == current_key) {
return; //no update required in the end
@@ -824,7 +822,18 @@ uniform float distance_fade_max : hint_range(0.0, 4096.0, 0.01);
)";
}
- if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && flags[FLAG_UV1_USE_TRIPLANAR]) {
+ String msg = "MSDF is not supported on triplanar materials. Ignoring MSDF in favor of triplanar mapping.";
+ if (textures[TEXTURE_ALBEDO].is_valid()) {
+ WARN_PRINT(vformat("%s (albedo %s): " + msg, get_path(), textures[TEXTURE_ALBEDO]->get_path()));
+ } else if (!get_path().is_empty()) {
+ WARN_PRINT(vformat("%s: " + msg, get_path()));
+ } else {
+ WARN_PRINT(msg);
+ }
+ }
+
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) {
code += R"(
uniform float msdf_pixel_range : hint_range(1.0, 100.0, 1.0);
uniform float msdf_outline_size : hint_range(0.0, 250.0, 1.0);
@@ -1273,7 +1282,7 @@ void vertex() {)";
code += "}\n";
- if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) {
code += R"(
float msdf_median(float r, float g, float b, float a) {
return min(max(min(r, g), min(max(r, g), b)), a);
@@ -1416,7 +1425,7 @@ void fragment() {)";
}
}
- if (flags[FLAG_ALBEDO_TEXTURE_MSDF]) {
+ if (flags[FLAG_ALBEDO_TEXTURE_MSDF] && !flags[FLAG_UV1_USE_TRIPLANAR]) {
code += R"(
{
// Albedo Texture MSDF: Enabled
@@ -1429,11 +1438,7 @@ void fragment() {)";
if (flags[FLAG_USE_POINT_SIZE]) {
code += " vec2 dest_size = vec2(1.0) / fwidth(POINT_COORD);\n";
} else {
- if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += " vec2 dest_size = vec2(1.0) / fwidth(uv1_triplanar_pos);\n";
- } else {
- code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n";
- }
+ code += " vec2 dest_size = vec2(1.0) / fwidth(base_uv);\n";
}
code += R"(
float px_size = max(0.5 * dot(msdf_size, dest_size), 1.0);
@@ -1855,6 +1860,7 @@ void BaseMaterial3D::flush_changes() {
while (dirty_materials.first()) {
dirty_materials.first()->self()->_update_shader();
+ dirty_materials.first()->remove_from_list();
}
}
@@ -1866,12 +1872,6 @@ void BaseMaterial3D::_queue_shader_change() {
}
}
-bool BaseMaterial3D::_is_shader_dirty() const {
- MutexLock lock(material_mutex);
-
- return element.in_list();
-}
-
void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
@@ -2824,7 +2824,7 @@ BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
RID BaseMaterial3D::get_shader_rid() const {
MutexLock lock(material_mutex);
- if (element.in_list()) { // _is_shader_dirty() would create anoder mutex lock
+ if (element.in_list()) {
((BaseMaterial3D *)this)->_update_shader();
}
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
@@ -3412,7 +3412,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change));
+ _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change), callable_mp(this, &BaseMaterial3D::_update_shader));
}
BaseMaterial3D::~BaseMaterial3D() {