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.cpp361
1 files changed, 221 insertions, 140 deletions
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 927e76e4b2..ecc1982aa5 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -46,11 +46,15 @@ void Material::set_next_pass(const Ref<Material> &p_pass) {
}
next_pass = p_pass;
- RID next_pass_rid;
- if (next_pass.is_valid()) {
- next_pass_rid = next_pass->get_rid();
+
+ if (material.is_valid()) {
+ RID next_pass_rid;
+ if (next_pass.is_valid()) {
+ next_pass_rid = next_pass->get_rid();
+ }
+
+ RS::get_singleton()->material_set_next_pass(material, next_pass_rid);
}
- RS::get_singleton()->material_set_next_pass(material, next_pass_rid);
}
Ref<Material> Material::get_next_pass() const {
@@ -61,7 +65,10 @@ void Material::set_render_priority(int p_priority) {
ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN);
ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX);
render_priority = p_priority;
- RS::get_singleton()->material_set_render_priority(material, p_priority);
+
+ if (material.is_valid()) {
+ RS::get_singleton()->material_set_render_priority(material, p_priority);
+ }
}
int Material::get_render_priority() const {
@@ -113,12 +120,12 @@ void Material::inspect_native_shader_code() {
RID Material::get_shader_rid() const {
RID ret;
- GDVIRTUAL_REQUIRED_CALL(_get_shader_rid, ret);
+ GDVIRTUAL_CALL(_get_shader_rid, ret);
return ret;
}
Shader::Mode Material::get_shader_mode() const {
Shader::Mode ret = Shader::MODE_MAX;
- GDVIRTUAL_REQUIRED_CALL(_get_shader_mode, ret);
+ GDVIRTUAL_CALL(_get_shader_mode, ret);
return ret;
}
@@ -165,13 +172,14 @@ void Material::_bind_methods() {
}
Material::Material() {
- material = RenderingServer::get_singleton()->material_create();
render_priority = 0;
}
Material::~Material() {
- ERR_FAIL_NULL(RenderingServer::get_singleton());
- RenderingServer::get_singleton()->free(material);
+ if (material.is_valid()) {
+ ERR_FAIL_NULL(RenderingServer::get_singleton());
+ RenderingServer::get_singleton()->free(material);
+ }
}
///////////////////////////////////
@@ -374,14 +382,11 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
bool ShaderMaterial::_property_can_revert(const StringName &p_name) const {
if (shader.is_valid()) {
- 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_shader_parameter(*pr);
- return default_value.get_type() != Variant::NIL && default_value != current_value;
- } else if (p_name == "render_priority" || p_name == "next_pass") {
+ if (remap_cache.has(p_name)) {
return true;
}
+ const String sname = p_name;
+ return sname == "render_priority" || sname == "next_pass";
}
return false;
}
@@ -422,7 +427,11 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
}
}
- RS::get_singleton()->material_set_shader(_get_material(), rid);
+ RID material_rid = _get_material();
+ if (material_rid.is_valid()) {
+ RS::get_singleton()->material_set_shader(material_rid, rid);
+ }
+
notify_property_list_changed(); //properties for shader exposed
emit_changed();
}
@@ -432,9 +441,12 @@ Ref<Shader> ShaderMaterial::get_shader() const {
}
void ShaderMaterial::set_shader_parameter(const StringName &p_param, const Variant &p_value) {
+ RID material_rid = _get_material();
if (p_value.get_type() == Variant::NIL) {
param_cache.erase(p_param);
- RS::get_singleton()->material_set_param(_get_material(), p_param, Variant());
+ if (material_rid.is_valid()) {
+ RS::get_singleton()->material_set_param(material_rid, p_param, Variant());
+ }
} else {
Variant *v = param_cache.getptr(p_param);
if (!v) {
@@ -449,12 +461,15 @@ void ShaderMaterial::set_shader_parameter(const StringName &p_param, const Varia
RID tex_rid = p_value;
if (tex_rid == RID()) {
param_cache.erase(p_param);
- RS::get_singleton()->material_set_param(_get_material(), p_param, Variant());
- } else {
- RS::get_singleton()->material_set_param(_get_material(), p_param, tex_rid);
+
+ if (material_rid.is_valid()) {
+ RS::get_singleton()->material_set_param(material_rid, p_param, Variant());
+ }
+ } else if (material_rid.is_valid()) {
+ RS::get_singleton()->material_set_param(material_rid, p_param, tex_rid);
}
- } else {
- RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
+ } else if (material_rid.is_valid()) {
+ RS::get_singleton()->material_set_param(material_rid, p_param, p_value);
}
}
}
@@ -471,6 +486,32 @@ void ShaderMaterial::_shader_changed() {
notify_property_list_changed(); //update all properties
}
+void ShaderMaterial::_check_material_rid() const {
+ MutexLock lock(material_rid_mutex);
+ if (_get_material().is_null()) {
+ RID shader_rid = shader.is_valid() ? shader->get_rid() : RID();
+ RID next_pass_rid;
+ if (get_next_pass().is_valid()) {
+ next_pass_rid = get_next_pass()->get_rid();
+ }
+
+ _set_material(RS::get_singleton()->material_create_from_shader(next_pass_rid, get_render_priority(), shader_rid));
+
+ for (KeyValue<StringName, Variant> param : param_cache) {
+ if (param.value.get_type() == Variant::OBJECT) {
+ RID tex_rid = param.value;
+ if (tex_rid.is_valid()) {
+ RS::get_singleton()->material_set_param(_get_material(), param.key, tex_rid);
+ } else {
+ RS::get_singleton()->material_set_param(_get_material(), param.key, Variant());
+ }
+ } else {
+ RS::get_singleton()->material_set_param(_get_material(), param.key, param.value);
+ }
+ }
+ }
+}
+
void ShaderMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader);
ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader);
@@ -511,6 +552,12 @@ Shader::Mode ShaderMaterial::get_shader_mode() const {
return Shader::MODE_SPATIAL;
}
}
+
+RID ShaderMaterial::get_rid() const {
+ _check_material_rid();
+ return Material::get_rid();
+}
+
RID ShaderMaterial::get_shader_rid() const {
if (shader.is_valid()) {
return shader->get_rid();
@@ -520,6 +567,7 @@ RID ShaderMaterial::get_shader_rid() const {
}
ShaderMaterial::ShaderMaterial() {
+ // Material RID will be empty until it is required.
}
ShaderMaterial::~ShaderMaterial() {
@@ -527,9 +575,8 @@ ShaderMaterial::~ShaderMaterial() {
/////////////////////////////////
-Mutex BaseMaterial3D::material_mutex;
-SelfList<BaseMaterial3D>::List BaseMaterial3D::dirty_materials;
HashMap<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData, BaseMaterial3D::MaterialKey> BaseMaterial3D::shader_map;
+Mutex BaseMaterial3D::shader_map_mutex;
BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = nullptr;
void BaseMaterial3D::init_shaders() {
@@ -619,22 +666,31 @@ HashMap<uint64_t, Ref<StandardMaterial3D>> BaseMaterial3D::materials_for_2d;
void BaseMaterial3D::finish_shaders() {
materials_for_2d.clear();
- dirty_materials.clear();
-
memdelete(shader_names);
shader_names = nullptr;
}
+void BaseMaterial3D::_mark_dirty() {
+ dirty = true;
+}
+
void BaseMaterial3D::_update_shader() {
+ if (!dirty) {
+ return;
+ }
+
+ dirty = false;
+
MaterialKey mk = _compute_key();
if (mk == current_key) {
return; //no update required in the end
}
+ MutexLock lock(shader_map_mutex);
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
if (shader_map[current_key].users == 0) {
- //deallocate shader, as it's no longer in use
+ // Deallocate shader which is no longer in use.
RS::get_singleton()->free(shader_map[current_key].shader);
shader_map.erase(current_key);
}
@@ -643,8 +699,13 @@ void BaseMaterial3D::_update_shader() {
current_key = mk;
if (shader_map.has(mk)) {
- RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
+ shader_rid = shader_map[mk].shader;
shader_map[mk].users++;
+
+ if (_get_material().is_valid()) {
+ RS::get_singleton()->material_set_shader(_get_material(), shader_rid);
+ }
+
return;
}
@@ -946,7 +1007,7 @@ uniform vec4 refraction_texture_channel;
code += "uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_linear_mipmap;\n";
}
- if (proximity_fade_enabled) {
+ if (features[FEATURE_REFRACTION] || proximity_fade_enabled) {
code += "uniform sampler2D depth_texture : hint_depth_texture, repeat_disable, filter_nearest;\n";
}
@@ -1627,7 +1688,14 @@ void fragment() {)";
}
code += R"(
float ref_amount = 1.0 - albedo.a * albedo_tex.a;
- EMISSION += textureLod(screen_texture, ref_ofs, ROUGHNESS * 8.0).rgb * ref_amount * EXPOSURE;
+
+ float refraction_depth_tex = textureLod(depth_texture, ref_ofs, 0.0).r;
+ vec4 refraction_view_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, refraction_depth_tex, 1.0);
+ refraction_view_pos.xyz /= refraction_view_pos.w;
+
+ // If the depth buffer is lower then the model's Z position, use the refracted UV, otherwise use the normal screen UV.
+ // At low depth differences, decrease refraction intensity to avoid sudden discontinuities.
+ EMISSION += textureLod(screen_texture, mix(SCREEN_UV, ref_ofs, smoothstep(0.0, 1.0, VERTEX.z - refraction_view_pos.z)), ROUGHNESS * 8.0).rgb * ref_amount * EXPOSURE;
ALBEDO *= 1.0 - ref_amount;
// Force transparency on the material (required for refraction).
ALPHA = 1.0;
@@ -1649,10 +1717,10 @@ void fragment() {)";
if (proximity_fade_enabled) {
code += R"(
// Proximity Fade: Enabled
- float depth_tex = textureLod(depth_texture, SCREEN_UV, 0.0).r;
- vec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, depth_tex, 1.0);
- world_pos.xyz /= world_pos.w;
- ALPHA *= clamp(1.0 - smoothstep(world_pos.z + proximity_fade_distance, world_pos.z, VERTEX.z), 0.0, 1.0);
+ float proximity_depth_tex = textureLod(depth_texture, SCREEN_UV, 0.0).r;
+ vec4 proximity_view_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV * 2.0 - 1.0, proximity_depth_tex, 1.0);
+ proximity_view_pos.xyz /= proximity_view_pos.w;
+ ALPHA *= clamp(1.0 - smoothstep(proximity_view_pos.z + proximity_fade_distance, proximity_view_pos.z, VERTEX.z), 0.0, 1.0);
)";
}
@@ -1866,37 +1934,45 @@ void fragment() {)";
code += "}\n";
ShaderData shader_data;
- shader_data.shader = RS::get_singleton()->shader_create();
+ shader_data.shader = RS::get_singleton()->shader_create_from_code(code);
shader_data.users = 1;
-
- RS::get_singleton()->shader_set_code(shader_data.shader, code);
-
shader_map[mk] = shader_data;
+ shader_rid = shader_data.shader;
- RS::get_singleton()->material_set_shader(_get_material(), shader_data.shader);
+ if (_get_material().is_valid()) {
+ RS::get_singleton()->material_set_shader(_get_material(), shader_rid);
+ }
}
-void BaseMaterial3D::flush_changes() {
- MutexLock lock(material_mutex);
+void BaseMaterial3D::_check_material_rid() {
+ MutexLock lock(material_rid_mutex);
+ if (_get_material().is_null()) {
+ RID next_pass_rid;
+ if (get_next_pass().is_valid()) {
+ next_pass_rid = get_next_pass()->get_rid();
+ }
+
+ _set_material(RS::get_singleton()->material_create_from_shader(next_pass_rid, get_render_priority(), shader_rid));
+
+ for (KeyValue<StringName, Variant> param : pending_params) {
+ RS::get_singleton()->material_set_param(_get_material(), param.key, param.value);
+ }
- while (dirty_materials.first()) {
- dirty_materials.first()->self()->_update_shader();
- dirty_materials.first()->remove_from_list();
+ pending_params.clear();
}
}
-void BaseMaterial3D::_queue_shader_change() {
- MutexLock lock(material_mutex);
-
- if (_is_initialized() && !element.in_list()) {
- dirty_materials.add(&element);
+void BaseMaterial3D::_material_set_param(const StringName &p_name, const Variant &p_value) {
+ if (_get_material().is_valid()) {
+ RS::get_singleton()->material_set_param(_get_material(), p_name, p_value);
+ } else {
+ pending_params[p_name] = p_value;
}
}
void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
-
- RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo);
+ _material_set_param(shader_names->albedo, p_albedo);
}
Color BaseMaterial3D::get_albedo() const {
@@ -1905,7 +1981,7 @@ Color BaseMaterial3D::get_albedo() const {
void BaseMaterial3D::set_specular(float p_specular) {
specular = p_specular;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
+ _material_set_param(shader_names->specular, p_specular);
}
float BaseMaterial3D::get_specular() const {
@@ -1914,7 +1990,7 @@ float BaseMaterial3D::get_specular() const {
void BaseMaterial3D::set_roughness(float p_roughness) {
roughness = p_roughness;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness);
+ _material_set_param(shader_names->roughness, p_roughness);
}
float BaseMaterial3D::get_roughness() const {
@@ -1923,7 +1999,7 @@ float BaseMaterial3D::get_roughness() const {
void BaseMaterial3D::set_metallic(float p_metallic) {
metallic = p_metallic;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
+ _material_set_param(shader_names->metallic, p_metallic);
}
float BaseMaterial3D::get_metallic() const {
@@ -1932,7 +2008,7 @@ float BaseMaterial3D::get_metallic() const {
void BaseMaterial3D::set_emission(const Color &p_emission) {
emission = p_emission;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission);
+ _material_set_param(shader_names->emission, p_emission);
}
Color BaseMaterial3D::get_emission() const {
@@ -1941,10 +2017,11 @@ Color BaseMaterial3D::get_emission() const {
void BaseMaterial3D::set_emission_energy_multiplier(float p_emission_energy_multiplier) {
emission_energy_multiplier = p_emission_energy_multiplier;
+
if (GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units")) {
- RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy_multiplier * emission_intensity);
+ _material_set_param(shader_names->emission_energy, p_emission_energy_multiplier * emission_intensity);
} else {
- RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy_multiplier);
+ _material_set_param(shader_names->emission_energy, p_emission_energy_multiplier);
}
}
@@ -1955,7 +2032,7 @@ float BaseMaterial3D::get_emission_energy_multiplier() const {
void BaseMaterial3D::set_emission_intensity(float p_emission_intensity) {
ERR_FAIL_COND_EDMSG(!GLOBAL_GET("rendering/lights_and_shadows/use_physical_light_units"), "Cannot set material emission intensity when Physical Light Units disabled.");
emission_intensity = p_emission_intensity;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, emission_energy_multiplier * emission_intensity);
+ _material_set_param(shader_names->emission_energy, emission_energy_multiplier * emission_intensity);
}
float BaseMaterial3D::get_emission_intensity() const {
@@ -1964,7 +2041,7 @@ float BaseMaterial3D::get_emission_intensity() const {
void BaseMaterial3D::set_normal_scale(float p_normal_scale) {
normal_scale = p_normal_scale;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale);
+ _material_set_param(shader_names->normal_scale, p_normal_scale);
}
float BaseMaterial3D::get_normal_scale() const {
@@ -1973,7 +2050,7 @@ float BaseMaterial3D::get_normal_scale() const {
void BaseMaterial3D::set_rim(float p_rim) {
rim = p_rim;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim);
+ _material_set_param(shader_names->rim, p_rim);
}
float BaseMaterial3D::get_rim() const {
@@ -1982,7 +2059,7 @@ float BaseMaterial3D::get_rim() const {
void BaseMaterial3D::set_rim_tint(float p_rim_tint) {
rim_tint = p_rim_tint;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint);
+ _material_set_param(shader_names->rim_tint, p_rim_tint);
}
float BaseMaterial3D::get_rim_tint() const {
@@ -1991,7 +2068,7 @@ float BaseMaterial3D::get_rim_tint() const {
void BaseMaterial3D::set_ao_light_affect(float p_ao_light_affect) {
ao_light_affect = p_ao_light_affect;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect);
+ _material_set_param(shader_names->ao_light_affect, p_ao_light_affect);
}
float BaseMaterial3D::get_ao_light_affect() const {
@@ -2000,7 +2077,7 @@ float BaseMaterial3D::get_ao_light_affect() const {
void BaseMaterial3D::set_clearcoat(float p_clearcoat) {
clearcoat = p_clearcoat;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat);
+ _material_set_param(shader_names->clearcoat, p_clearcoat);
}
float BaseMaterial3D::get_clearcoat() const {
@@ -2009,7 +2086,7 @@ float BaseMaterial3D::get_clearcoat() const {
void BaseMaterial3D::set_clearcoat_roughness(float p_clearcoat_roughness) {
clearcoat_roughness = p_clearcoat_roughness;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_roughness, p_clearcoat_roughness);
+ _material_set_param(shader_names->clearcoat_roughness, p_clearcoat_roughness);
}
float BaseMaterial3D::get_clearcoat_roughness() const {
@@ -2018,7 +2095,7 @@ float BaseMaterial3D::get_clearcoat_roughness() const {
void BaseMaterial3D::set_anisotropy(float p_anisotropy) {
anisotropy = p_anisotropy;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy);
+ _material_set_param(shader_names->anisotropy, p_anisotropy);
}
float BaseMaterial3D::get_anisotropy() const {
@@ -2027,7 +2104,7 @@ float BaseMaterial3D::get_anisotropy() const {
void BaseMaterial3D::set_heightmap_scale(float p_heightmap_scale) {
heightmap_scale = p_heightmap_scale;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_scale, p_heightmap_scale);
+ _material_set_param(shader_names->heightmap_scale, p_heightmap_scale);
}
float BaseMaterial3D::get_heightmap_scale() const {
@@ -2036,7 +2113,7 @@ float BaseMaterial3D::get_heightmap_scale() const {
void BaseMaterial3D::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
subsurface_scattering_strength = p_subsurface_scattering_strength;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength);
+ _material_set_param(shader_names->subsurface_scattering_strength, subsurface_scattering_strength);
}
float BaseMaterial3D::get_subsurface_scattering_strength() const {
@@ -2045,7 +2122,7 @@ float BaseMaterial3D::get_subsurface_scattering_strength() const {
void BaseMaterial3D::set_transmittance_color(const Color &p_color) {
transmittance_color = p_color;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_color, p_color);
+ _material_set_param(shader_names->transmittance_color, p_color);
}
Color BaseMaterial3D::get_transmittance_color() const {
@@ -2054,7 +2131,7 @@ Color BaseMaterial3D::get_transmittance_color() const {
void BaseMaterial3D::set_transmittance_depth(float p_depth) {
transmittance_depth = p_depth;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_depth, p_depth);
+ _material_set_param(shader_names->transmittance_depth, p_depth);
}
float BaseMaterial3D::get_transmittance_depth() const {
@@ -2063,7 +2140,7 @@ float BaseMaterial3D::get_transmittance_depth() const {
void BaseMaterial3D::set_transmittance_boost(float p_boost) {
transmittance_boost = p_boost;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
+ _material_set_param(shader_names->transmittance_boost, p_boost);
}
float BaseMaterial3D::get_transmittance_boost() const {
@@ -2072,7 +2149,7 @@ float BaseMaterial3D::get_transmittance_boost() const {
void BaseMaterial3D::set_backlight(const Color &p_backlight) {
backlight = p_backlight;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->backlight, backlight);
+ _material_set_param(shader_names->backlight, backlight);
}
Color BaseMaterial3D::get_backlight() const {
@@ -2081,7 +2158,7 @@ Color BaseMaterial3D::get_backlight() const {
void BaseMaterial3D::set_refraction(float p_refraction) {
refraction = p_refraction;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction);
+ _material_set_param(shader_names->refraction, refraction);
}
float BaseMaterial3D::get_refraction() const {
@@ -2094,7 +2171,7 @@ void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) {
}
detail_uv = p_detail_uv;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
@@ -2107,7 +2184,7 @@ void BaseMaterial3D::set_blend_mode(BlendMode p_mode) {
}
blend_mode = p_mode;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
@@ -2116,7 +2193,7 @@ BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) {
detail_blend_mode = p_mode;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
@@ -2129,7 +2206,7 @@ void BaseMaterial3D::set_transparency(Transparency p_transparency) {
}
transparency = p_transparency;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2143,7 +2220,7 @@ void BaseMaterial3D::set_alpha_antialiasing(AlphaAntiAliasing p_alpha_aa) {
}
alpha_antialiasing_mode = p_alpha_aa;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2157,7 +2234,7 @@ void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
}
shading_mode = p_shading_mode;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2171,7 +2248,7 @@ void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) {
}
depth_draw_mode = p_mode;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
@@ -2184,7 +2261,7 @@ void BaseMaterial3D::set_cull_mode(CullMode p_mode) {
}
cull_mode = p_mode;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
@@ -2197,7 +2274,7 @@ void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) {
}
diffuse_mode = p_mode;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
@@ -2210,7 +2287,7 @@ void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) {
}
specular_mode = p_mode;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
@@ -2240,7 +2317,7 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
update_configuration_warning();
}
- _queue_shader_change();
+ _mark_dirty();
}
bool BaseMaterial3D::get_flag(Flags p_flag) const {
@@ -2256,7 +2333,7 @@ void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
features[p_feature] = p_enabled;
notify_property_list_changed();
- _queue_shader_change();
+ _mark_dirty();
}
bool BaseMaterial3D::get_feature(Feature p_feature) const {
@@ -2269,15 +2346,14 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t
textures[p_param] = p_texture;
Variant rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant();
- RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
+ _material_set_param(shader_names->texture_names[p_param], rid);
if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) {
- RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size,
- Vector2i(p_texture->get_width(), p_texture->get_height()));
+ _material_set_param(shader_names->albedo_texture_size, Vector2i(p_texture->get_width(), p_texture->get_height()));
}
notify_property_list_changed();
- _queue_shader_change();
+ _mark_dirty();
}
Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
@@ -2297,7 +2373,7 @@ Ref<Texture2D> BaseMaterial3D::get_texture_by_name(const StringName &p_name) con
void BaseMaterial3D::set_texture_filter(TextureFilter p_filter) {
texture_filter = p_filter;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::TextureFilter BaseMaterial3D::get_texture_filter() const {
@@ -2469,7 +2545,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &p_property) const {
void BaseMaterial3D::set_point_size(float p_point_size) {
point_size = p_point_size;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size);
+ _material_set_param(shader_names->point_size, p_point_size);
}
float BaseMaterial3D::get_point_size() const {
@@ -2478,7 +2554,7 @@ float BaseMaterial3D::get_point_size() const {
void BaseMaterial3D::set_uv1_scale(const Vector3 &p_scale) {
uv1_scale = p_scale;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
+ _material_set_param(shader_names->uv1_scale, p_scale);
}
Vector3 BaseMaterial3D::get_uv1_scale() const {
@@ -2487,7 +2563,7 @@ Vector3 BaseMaterial3D::get_uv1_scale() const {
void BaseMaterial3D::set_uv1_offset(const Vector3 &p_offset) {
uv1_offset = p_offset;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
+ _material_set_param(shader_names->uv1_offset, p_offset);
}
Vector3 BaseMaterial3D::get_uv1_offset() const {
@@ -2497,7 +2573,7 @@ Vector3 BaseMaterial3D::get_uv1_offset() const {
void BaseMaterial3D::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
// Negative values or values higher than 150 can result in NaNs, leading to broken rendering.
uv1_triplanar_sharpness = CLAMP(p_sharpness, 0.0, 150.0);
- RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, uv1_triplanar_sharpness);
+ _material_set_param(shader_names->uv1_blend_sharpness, uv1_triplanar_sharpness);
}
float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const {
@@ -2506,7 +2582,7 @@ float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const {
void BaseMaterial3D::set_uv2_scale(const Vector3 &p_scale) {
uv2_scale = p_scale;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
+ _material_set_param(shader_names->uv2_scale, p_scale);
}
Vector3 BaseMaterial3D::get_uv2_scale() const {
@@ -2515,7 +2591,7 @@ Vector3 BaseMaterial3D::get_uv2_scale() const {
void BaseMaterial3D::set_uv2_offset(const Vector3 &p_offset) {
uv2_offset = p_offset;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
+ _material_set_param(shader_names->uv2_offset, p_offset);
}
Vector3 BaseMaterial3D::get_uv2_offset() const {
@@ -2525,7 +2601,7 @@ Vector3 BaseMaterial3D::get_uv2_offset() const {
void BaseMaterial3D::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
// Negative values or values higher than 150 can result in NaNs, leading to broken rendering.
uv2_triplanar_sharpness = CLAMP(p_sharpness, 0.0, 150.0);
- RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, uv2_triplanar_sharpness);
+ _material_set_param(shader_names->uv2_blend_sharpness, uv2_triplanar_sharpness);
}
float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {
@@ -2534,7 +2610,7 @@ float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {
void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) {
billboard_mode = p_mode;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2544,7 +2620,7 @@ BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const {
void BaseMaterial3D::set_particles_anim_h_frames(int p_frames) {
particles_anim_h_frames = p_frames;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
+ _material_set_param(shader_names->particles_anim_h_frames, p_frames);
}
int BaseMaterial3D::get_particles_anim_h_frames() const {
@@ -2553,7 +2629,7 @@ int BaseMaterial3D::get_particles_anim_h_frames() const {
void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) {
particles_anim_v_frames = p_frames;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
+ _material_set_param(shader_names->particles_anim_v_frames, p_frames);
}
int BaseMaterial3D::get_particles_anim_v_frames() const {
@@ -2562,7 +2638,7 @@ int BaseMaterial3D::get_particles_anim_v_frames() const {
void BaseMaterial3D::set_particles_anim_loop(bool p_loop) {
particles_anim_loop = p_loop;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop);
+ _material_set_param(shader_names->particles_anim_loop, particles_anim_loop);
}
bool BaseMaterial3D::get_particles_anim_loop() const {
@@ -2571,7 +2647,7 @@ bool BaseMaterial3D::get_particles_anim_loop() const {
void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) {
deep_parallax = p_enable;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2581,7 +2657,7 @@ bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const {
void BaseMaterial3D::set_heightmap_deep_parallax_min_layers(int p_layer) {
deep_parallax_min_layers = p_layer;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_min_layers, p_layer);
+ _material_set_param(shader_names->heightmap_min_layers, p_layer);
}
int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
@@ -2590,7 +2666,7 @@ int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
void BaseMaterial3D::set_heightmap_deep_parallax_max_layers(int p_layer) {
deep_parallax_max_layers = p_layer;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_max_layers, p_layer);
+ _material_set_param(shader_names->heightmap_max_layers, p_layer);
}
int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
@@ -2599,7 +2675,7 @@ int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
void BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent(bool p_flip) {
heightmap_parallax_flip_tangent = p_flip;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
+ _material_set_param(shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const {
@@ -2608,7 +2684,7 @@ bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const {
void BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal(bool p_flip) {
heightmap_parallax_flip_binormal = p_flip;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
+ _material_set_param(shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {
@@ -2617,7 +2693,7 @@ bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {
void BaseMaterial3D::set_grow_enabled(bool p_enable) {
grow_enabled = p_enable;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2627,7 +2703,7 @@ bool BaseMaterial3D::is_grow_enabled() const {
void BaseMaterial3D::set_alpha_scissor_threshold(float p_threshold) {
alpha_scissor_threshold = p_threshold;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_scissor_threshold, p_threshold);
+ _material_set_param(shader_names->alpha_scissor_threshold, p_threshold);
}
float BaseMaterial3D::get_alpha_scissor_threshold() const {
@@ -2636,7 +2712,7 @@ float BaseMaterial3D::get_alpha_scissor_threshold() const {
void BaseMaterial3D::set_alpha_hash_scale(float p_scale) {
alpha_hash_scale = p_scale;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_hash_scale, p_scale);
+ _material_set_param(shader_names->alpha_hash_scale, p_scale);
}
float BaseMaterial3D::get_alpha_hash_scale() const {
@@ -2645,7 +2721,7 @@ float BaseMaterial3D::get_alpha_hash_scale() const {
void BaseMaterial3D::set_alpha_antialiasing_edge(float p_edge) {
alpha_antialiasing_edge = p_edge;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->alpha_antialiasing_edge, p_edge);
+ _material_set_param(shader_names->alpha_antialiasing_edge, p_edge);
}
float BaseMaterial3D::get_alpha_antialiasing_edge() const {
@@ -2654,7 +2730,7 @@ float BaseMaterial3D::get_alpha_antialiasing_edge() const {
void BaseMaterial3D::set_grow(float p_grow) {
grow = p_grow;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->grow, p_grow);
+ _material_set_param(shader_names->grow, p_grow);
}
float BaseMaterial3D::get_grow() const {
@@ -2676,7 +2752,7 @@ static Plane _get_texture_mask(BaseMaterial3D::TextureChannel p_channel) {
void BaseMaterial3D::set_metallic_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
metallic_texture_channel = p_channel;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic_texture_channel, _get_texture_mask(p_channel));
+ _material_set_param(shader_names->metallic_texture_channel, _get_texture_mask(p_channel));
}
BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() const {
@@ -2686,7 +2762,7 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() co
void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
roughness_texture_channel = p_channel;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() const {
@@ -2696,7 +2772,7 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() c
void BaseMaterial3D::set_ao_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
ao_texture_channel = p_channel;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel));
+ _material_set_param(shader_names->ao_texture_channel, _get_texture_mask(p_channel));
}
BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const {
@@ -2706,7 +2782,7 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const {
void BaseMaterial3D::set_refraction_texture_channel(TextureChannel p_channel) {
ERR_FAIL_INDEX(p_channel, 5);
refraction_texture_channel = p_channel;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
+ _material_set_param(shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
}
BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel() const {
@@ -2768,7 +2844,7 @@ void BaseMaterial3D::set_on_top_of_alpha() {
void BaseMaterial3D::set_proximity_fade_enabled(bool p_enable) {
proximity_fade_enabled = p_enable;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2778,7 +2854,7 @@ bool BaseMaterial3D::is_proximity_fade_enabled() const {
void BaseMaterial3D::set_proximity_fade_distance(float p_distance) {
proximity_fade_distance = MAX(p_distance, 0.01);
- RS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, proximity_fade_distance);
+ _material_set_param(shader_names->proximity_fade_distance, proximity_fade_distance);
}
float BaseMaterial3D::get_proximity_fade_distance() const {
@@ -2787,7 +2863,7 @@ float BaseMaterial3D::get_proximity_fade_distance() const {
void BaseMaterial3D::set_msdf_pixel_range(float p_range) {
msdf_pixel_range = p_range;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->msdf_pixel_range, p_range);
+ _material_set_param(shader_names->msdf_pixel_range, p_range);
}
float BaseMaterial3D::get_msdf_pixel_range() const {
@@ -2796,7 +2872,7 @@ float BaseMaterial3D::get_msdf_pixel_range() const {
void BaseMaterial3D::set_msdf_outline_size(float p_size) {
msdf_outline_size = p_size;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->msdf_outline_size, p_size);
+ _material_set_param(shader_names->msdf_outline_size, p_size);
}
float BaseMaterial3D::get_msdf_outline_size() const {
@@ -2805,7 +2881,7 @@ float BaseMaterial3D::get_msdf_outline_size() const {
void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
distance_fade = p_mode;
- _queue_shader_change();
+ _mark_dirty();
notify_property_list_changed();
}
@@ -2815,7 +2891,7 @@ BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
void BaseMaterial3D::set_distance_fade_max_distance(float p_distance) {
distance_fade_max_distance = p_distance;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance);
+ _material_set_param(shader_names->distance_fade_max, distance_fade_max_distance);
}
float BaseMaterial3D::get_distance_fade_max_distance() const {
@@ -2824,7 +2900,7 @@ float BaseMaterial3D::get_distance_fade_max_distance() const {
void BaseMaterial3D::set_distance_fade_min_distance(float p_distance) {
distance_fade_min_distance = p_distance;
- RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance);
+ _material_set_param(shader_names->distance_fade_min, distance_fade_min_distance);
}
float BaseMaterial3D::get_distance_fade_min_distance() const {
@@ -2836,20 +2912,22 @@ void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) {
return;
}
emission_op = p_op;
- _queue_shader_change();
+ _mark_dirty();
}
BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
return emission_op;
}
+RID BaseMaterial3D::get_rid() const {
+ const_cast<BaseMaterial3D *>(this)->_update_shader();
+ const_cast<BaseMaterial3D *>(this)->_check_material_rid();
+ return _get_material();
+}
+
RID BaseMaterial3D::get_shader_rid() const {
- MutexLock lock(material_mutex);
- if (element.in_list()) {
- ((BaseMaterial3D *)this)->_update_shader();
- }
- ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
- return shader_map[current_key].shader;
+ const_cast<BaseMaterial3D *>(this)->_update_shader();
+ return shader_rid;
}
Shader::Mode BaseMaterial3D::get_shader_mode() const {
@@ -3365,8 +3443,7 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(DISTANCE_FADE_OBJECT_DITHER);
}
-BaseMaterial3D::BaseMaterial3D(bool p_orm) :
- element(this) {
+BaseMaterial3D::BaseMaterial3D(bool p_orm) {
orm = p_orm;
// Initialize to the same values as the shader
set_albedo(Color(1.0, 1.0, 1.0, 1.0));
@@ -3433,21 +3510,25 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
current_key.invalid_key = 1;
- _mark_initialized(callable_mp(this, &BaseMaterial3D::_queue_shader_change), callable_mp(this, &BaseMaterial3D::_update_shader));
+ _mark_dirty();
}
BaseMaterial3D::~BaseMaterial3D() {
- ERR_FAIL_NULL(RenderingServer::get_singleton());
- MutexLock lock(material_mutex);
+ ERR_FAIL_NULL(RS::get_singleton());
- if (shader_map.has(current_key)) {
- shader_map[current_key].users--;
- if (shader_map[current_key].users == 0) {
- //deallocate shader, as it's no longer in use
- RS::get_singleton()->free(shader_map[current_key].shader);
- shader_map.erase(current_key);
+ {
+ MutexLock lock(shader_map_mutex);
+ if (shader_map.has(current_key)) {
+ shader_map[current_key].users--;
+ if (shader_map[current_key].users == 0) {
+ // Deallocate shader which is no longer in use.
+ RS::get_singleton()->free(shader_map[current_key].shader);
+ shader_map.erase(current_key);
+ }
}
+ }
+ if (_get_material().is_valid()) {
RS::get_singleton()->material_set_shader(_get_material(), RID());
}
}