diff options
Diffstat (limited to 'scene/resources/material.cpp')
-rw-r--r-- | scene/resources/material.cpp | 127 |
1 files changed, 73 insertions, 54 deletions
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 3e2a952ea7..7e84814ab3 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -113,6 +113,12 @@ bool Material::_can_use_render_priority() const { return ret; } +Ref<Resource> Material::create_placeholder() const { + Ref<PlaceholderMaterial> placeholder; + placeholder.instantiate(); + return placeholder; +} + void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass); ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass); @@ -123,6 +129,8 @@ void Material::_bind_methods() { ClassDB::bind_method(D_METHOD("inspect_native_shader_code"), &Material::inspect_native_shader_code); ClassDB::set_method_flags(get_class_static(), _scs_create("inspect_native_shader_code"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); + ClassDB::bind_method(D_METHOD("create_placeholder"), &Material::create_placeholder); + ADD_PROPERTY(PropertyInfo(Variant::INT, "render_priority", PROPERTY_HINT_RANGE, itos(RENDER_PRIORITY_MIN) + "," + itos(RENDER_PRIORITY_MAX) + ",1"), "set_render_priority", "get_render_priority"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "next_pass", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_next_pass", "get_next_pass"); @@ -149,11 +157,36 @@ Material::~Material() { bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { if (shader.is_valid()) { - StringName pr = shader->remap_parameter(p_name); - if (pr) { - set_shader_parameter(pr, p_value); + const StringName *sn = remap_cache.getptr(p_name); + if (sn) { + set_shader_parameter(*sn, p_value); return true; } + String s = p_name; + if (s.begins_with("shader_parameter/")) { + String param = s.replace_first("shader_parameter/", ""); + remap_cache[s] = param; + set_shader_parameter(param, p_value); + return true; + } +#ifndef DISABLE_DEPRECATED + // Compatibility remaps are only needed here. + if (s.begins_with("param/")) { + s = s.replace_first("param/", "shader_parameter/"); + } else if (s.begins_with("shader_param/")) { + s = s.replace_first("shader_param/", "shader_parameter/"); + } else if (s.begins_with("shader_uniform/")) { + s = s.replace_first("shader_uniform/", "shader_parameter/"); + } else { + return false; // Not a shader parameter. + } + + WARN_PRINT("This material (containing shader with path: '" + shader->get_path() + "') uses an old deprecated parameter names. Consider re-saving this resource (or scene which contains it) in order for it to continue working in future versions."); + String param = s.replace_first("shader_parameter/", ""); + remap_cache[s] = param; + set_shader_parameter(param, p_value); + return true; +#endif } return false; @@ -161,9 +194,10 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) { bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const { if (shader.is_valid()) { - StringName pr = shader->remap_parameter(p_name); - if (pr) { - r_ret = get_shader_parameter(pr); + const StringName *sn = remap_cache.getptr(p_name); + if (sn) { + // Only return a parameter if it was previously set. + r_ret = get_shader_parameter(*sn); return true; } } @@ -247,6 +281,12 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { PropertyInfo info = E->get(); info.name = "shader_parameter/" + info.name; + if (!param_cache.has(E->get().name)) { + // Property has never been edited, retrieve with default value. + Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), E->get().name); + param_cache.insert(E->get().name, default_value); + remap_cache.insert(info.name, E->get().name); + } groups[last_group][last_subgroup].push_back(info); } @@ -275,11 +315,10 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { bool ShaderMaterial::_property_can_revert(const StringName &p_name) const { if (shader.is_valid()) { - StringName pr = shader->remap_parameter(p_name); + const StringName *pr = remap_cache.getptr(p_name); if (pr) { - Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr); - Variant current_value; - _get(p_name, current_value); + Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr); + Variant current_value = get_shader_parameter(*pr); return default_value.get_type() != Variant::NIL && default_value != current_value; } } @@ -288,9 +327,9 @@ bool ShaderMaterial::_property_can_revert(const StringName &p_name) const { bool ShaderMaterial::_property_get_revert(const StringName &p_name, Variant &r_property) const { if (shader.is_valid()) { - StringName pr = shader->remap_parameter(p_name); - if (pr) { - r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr); + const StringName *pr = remap_cache.getptr(p_name); + if (*pr) { + r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr); return true; } } @@ -2277,71 +2316,51 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() return refraction_texture_channel; } -Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, RID *r_shader_rid) { - int64_t hash = 0; - if (p_shaded) { - hash |= 1 << 0; - } - if (p_transparent) { - hash |= 1 << 1; - } - if (p_cut_alpha) { - hash |= 1 << 2; - } - if (p_opaque_prepass) { - hash |= 1 << 3; - } - if (p_double_sided) { - hash |= 1 << 4; - } - if (p_billboard) { - hash |= 1 << 5; - } - if (p_billboard_y) { - hash |= 1 << 6; - } - if (p_msdf) { - hash |= 1 << 7; - } - if (p_no_depth) { - hash |= 1 << 8; - } - if (p_fixed_size) { - hash |= 1 << 9; - } - hash = hash_murmur3_one_64(p_filter, hash); - - if (materials_for_2d.has(hash)) { +Ref<Material> BaseMaterial3D::get_material_for_2d(bool p_shaded, Transparency p_transparency, bool p_double_sided, bool p_billboard, bool p_billboard_y, bool p_msdf, bool p_no_depth, bool p_fixed_size, TextureFilter p_filter, AlphaAntiAliasing p_alpha_antialiasing_mode, RID *r_shader_rid) { + uint64_t key = 0; + key |= ((int8_t)p_shaded & 0x01) << 0; + key |= ((int8_t)p_transparency & 0x07) << 1; // Bits 1-3. + key |= ((int8_t)p_double_sided & 0x01) << 4; + key |= ((int8_t)p_billboard & 0x01) << 5; + key |= ((int8_t)p_billboard_y & 0x01) << 6; + key |= ((int8_t)p_msdf & 0x01) << 7; + key |= ((int8_t)p_no_depth & 0x01) << 8; + key |= ((int8_t)p_fixed_size & 0x01) << 9; + key |= ((int8_t)p_filter & 0x07) << 10; // Bits 10-12. + key |= ((int8_t)p_alpha_antialiasing_mode & 0x07) << 13; // Bits 13-15. + + if (materials_for_2d.has(key)) { if (r_shader_rid) { - *r_shader_rid = materials_for_2d[hash]->get_shader_rid(); + *r_shader_rid = materials_for_2d[key]->get_shader_rid(); } - return materials_for_2d[hash]; + return materials_for_2d[key]; } Ref<StandardMaterial3D> material; material.instantiate(); material->set_shading_mode(p_shaded ? SHADING_MODE_PER_PIXEL : SHADING_MODE_UNSHADED); - material->set_transparency(p_transparent ? (p_opaque_prepass ? TRANSPARENCY_ALPHA_DEPTH_PRE_PASS : (p_cut_alpha ? TRANSPARENCY_ALPHA_SCISSOR : TRANSPARENCY_ALPHA)) : TRANSPARENCY_DISABLED); + material->set_transparency(p_transparency); material->set_cull_mode(p_double_sided ? CULL_DISABLED : CULL_BACK); material->set_flag(FLAG_SRGB_VERTEX_COLOR, true); material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true); material->set_flag(FLAG_ALBEDO_TEXTURE_MSDF, p_msdf); material->set_flag(FLAG_DISABLE_DEPTH_TEST, p_no_depth); material->set_flag(FLAG_FIXED_SIZE, p_fixed_size); + material->set_alpha_antialiasing(p_alpha_antialiasing_mode); material->set_texture_filter(p_filter); if (p_billboard || p_billboard_y) { material->set_flag(FLAG_BILLBOARD_KEEP_SCALE, true); material->set_billboard_mode(p_billboard_y ? BILLBOARD_FIXED_Y : BILLBOARD_ENABLED); } - materials_for_2d[hash] = material; + materials_for_2d[key] = material; if (r_shader_rid) { - *r_shader_rid = materials_for_2d[hash]->get_shader_rid(); + *r_shader_rid = materials_for_2d[key]->get_shader_rid(); } - return materials_for_2d[hash]; + return materials_for_2d[key]; } void BaseMaterial3D::set_on_top_of_alpha() { |