Merge pull request #74937 from bitsawer/fix_uniform_storage

Fix shader uniform storage conversions and crash
This commit is contained in:
Rémi Verschelde
2023-06-09 11:04:16 +02:00
7 changed files with 560 additions and 1148 deletions

View File

@@ -310,10 +310,34 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
vgroups.push_back(Pair<String, LocalVector<String>>("<None>", { "<None>" }));
}
const bool is_uniform_cached = param_cache.has(E->get().name);
bool is_uniform_type_compatible = true;
if (is_uniform_cached) {
// Check if the uniform Variant type changed, for example vec3 to vec4.
const Variant &cached = param_cache.get(E->get().name);
if (cached.is_array()) {
// Allow some array conversions for backwards compatibility.
is_uniform_type_compatible = Variant::can_convert(E->get().type, cached.get_type());
} else {
is_uniform_type_compatible = E->get().type == cached.get_type();
}
if (is_uniform_type_compatible && E->get().type == Variant::OBJECT && cached.get_type() == Variant::OBJECT) {
// Check if the Object class (hint string) changed, for example Texture2D sampler to Texture3D.
// Allow inheritance, Texture2D type sampler should also accept CompressedTexture2D.
Object *cached_obj = cached;
if (!cached_obj->is_class(E->get().hint_string)) {
is_uniform_type_compatible = false;
}
}
}
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.
if (!is_uniform_cached || !is_uniform_type_compatible) {
// Property has never been edited or its type changed, 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);