Merge pull request #71797 from reduz/cleanup-shader-parameter-remap
Clean up shader parameter remap
This commit is contained in:
commit
145ab2e1fd
5 changed files with 63 additions and 75 deletions
|
@ -26,12 +26,12 @@
|
|||
Returns the shader mode for the shader, either [constant MODE_CANVAS_ITEM], [constant MODE_SPATIAL] or [constant MODE_PARTICLES].
|
||||
</description>
|
||||
</method>
|
||||
<method name="has_parameter" qualifiers="const">
|
||||
<return type="bool" />
|
||||
<param index="0" name="name" type="StringName" />
|
||||
<method name="get_shader_uniform_list">
|
||||
<return type="Array" />
|
||||
<param index="0" name="get_groups" type="bool" default="false" />
|
||||
<description>
|
||||
Returns [code]true[/code] if the shader has this param defined as a uniform in its code.
|
||||
[b]Note:[/b] [param name] must match the name of the uniform in the code exactly.
|
||||
Get the list of shader uniforms that can be assigned to a [ShaderMaterial], for use with [method ShaderMaterial.set_shader_parameter] and [method ShaderMaterial.get_shader_parameter]. The parameters returned are contained in dictionaries in a similar format to the ones returned by [method Object.get_property_list].
|
||||
If argument [param get_groups] is true, parameter grouping hints will be provided.
|
||||
</description>
|
||||
</method>
|
||||
<method name="set_default_texture_parameter">
|
||||
|
|
|
@ -149,11 +149,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 +186,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 previosly set.
|
||||
r_ret = get_shader_parameter(*sn);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -247,6 +273,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 +307,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 +319,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,8 @@ class ShaderMaterial : public Material {
|
|||
GDCLASS(ShaderMaterial, Material);
|
||||
Ref<Shader> shader;
|
||||
|
||||
HashMap<StringName, Variant> param_cache;
|
||||
mutable HashMap<StringName, StringName> remap_cache;
|
||||
mutable HashMap<StringName, Variant> param_cache;
|
||||
|
||||
protected:
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
|
|
|
@ -43,7 +43,6 @@ Shader::Mode Shader::get_mode() const {
|
|||
|
||||
void Shader::_dependency_changed() {
|
||||
RenderingServer::get_singleton()->shader_set_code(shader, RenderingServer::get_singleton()->shader_get_code(shader));
|
||||
params_cache_dirty = true;
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
@ -93,7 +92,6 @@ void Shader::set_code(const String &p_code) {
|
|||
}
|
||||
|
||||
RenderingServer::get_singleton()->shader_set_code(shader, pp_code);
|
||||
params_cache_dirty = true;
|
||||
|
||||
emit_changed();
|
||||
}
|
||||
|
@ -108,8 +106,6 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr
|
|||
|
||||
List<PropertyInfo> local;
|
||||
RenderingServer::get_singleton()->get_shader_parameter_list(shader, &local);
|
||||
params_cache.clear();
|
||||
params_cache_dirty = false;
|
||||
|
||||
for (PropertyInfo &pi : local) {
|
||||
bool is_group = pi.usage == PROPERTY_USAGE_GROUP || pi.usage == PROPERTY_USAGE_SUBGROUP;
|
||||
|
@ -120,7 +116,6 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr
|
|||
if (default_textures.has(pi.name)) { //do not show default textures
|
||||
continue;
|
||||
}
|
||||
params_cache[pi.name] = pi.name;
|
||||
}
|
||||
if (p_params) {
|
||||
//small little hack
|
||||
|
@ -176,11 +171,17 @@ bool Shader::is_text_shader() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Shader::has_parameter(const StringName &p_name) const {
|
||||
return params_cache.has(p_name);
|
||||
void Shader::_update_shader() const {
|
||||
}
|
||||
|
||||
void Shader::_update_shader() const {
|
||||
Array Shader::_get_shader_uniform_list(bool p_get_groups) {
|
||||
List<PropertyInfo> uniform_list;
|
||||
get_shader_uniform_list(&uniform_list, p_get_groups);
|
||||
Array ret;
|
||||
for (const PropertyInfo &pi : uniform_list) {
|
||||
ret.push_back(pi.operator Dictionary());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Shader::_bind_methods() {
|
||||
|
@ -192,7 +193,7 @@ void Shader::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("set_default_texture_parameter", "name", "texture", "index"), &Shader::set_default_texture_parameter, DEFVAL(0));
|
||||
ClassDB::bind_method(D_METHOD("get_default_texture_parameter", "name", "index"), &Shader::get_default_texture_parameter, DEFVAL(0));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("has_parameter", "name"), &Shader::has_parameter);
|
||||
ClassDB::bind_method(D_METHOD("get_shader_uniform_list", "get_groups"), &Shader::_get_shader_uniform_list, DEFVAL(false));
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_code", "get_code");
|
||||
|
||||
|
|
|
@ -57,15 +57,12 @@ private:
|
|||
HashSet<Ref<ShaderInclude>> include_dependencies;
|
||||
String code;
|
||||
|
||||
// hack the name of performance
|
||||
// shaders keep a list of ShaderMaterial -> RenderingServer name translations, to make
|
||||
// conversion fast and save memory.
|
||||
mutable bool params_cache_dirty = true;
|
||||
mutable HashMap<StringName, StringName> params_cache; //map a shader param to a material param..
|
||||
HashMap<StringName, HashMap<int, Ref<Texture2D>>> default_textures;
|
||||
|
||||
void _dependency_changed();
|
||||
virtual void _update_shader() const; //used for visual shader
|
||||
Array _get_shader_uniform_list(bool p_get_groups = false);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -79,7 +76,6 @@ public:
|
|||
String get_code() const;
|
||||
|
||||
void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) const;
|
||||
bool has_parameter(const StringName &p_name) const;
|
||||
|
||||
void set_default_texture_parameter(const StringName &p_name, const Ref<Texture2D> &p_texture, int p_index = 0);
|
||||
Ref<Texture2D> get_default_texture_parameter(const StringName &p_name, int p_index = 0) const;
|
||||
|
@ -87,47 +83,6 @@ public:
|
|||
|
||||
virtual bool is_text_shader() const;
|
||||
|
||||
// Finds the shader parameter name for the given property name, which should start with "shader_parameter/".
|
||||
_FORCE_INLINE_ StringName remap_parameter(const StringName &p_property) const {
|
||||
if (params_cache_dirty) {
|
||||
get_shader_uniform_list(nullptr);
|
||||
}
|
||||
|
||||
String n = p_property;
|
||||
|
||||
// Backwards compatibility with old shader parameter names.
|
||||
// Note: The if statements are important to make sure we are only replacing text exactly at index 0.
|
||||
if (n.find("param/") == 0) {
|
||||
n = n.replace_first("param/", "shader_parameter/");
|
||||
}
|
||||
if (n.find("shader_param/") == 0) {
|
||||
n = n.replace_first("shader_param/", "shader_parameter/");
|
||||
}
|
||||
if (n.find("shader_uniform/") == 0) {
|
||||
n = n.replace_first("shader_uniform/", "shader_parameter/");
|
||||
}
|
||||
|
||||
{
|
||||
// Additional backwards compatibility for projects between #62972 and #64092 (about a month of v4.0 development).
|
||||
// These projects did not have any prefix for shader uniforms due to a bug.
|
||||
// This code should be removed during beta or rc of 4.0.
|
||||
const HashMap<StringName, StringName>::Iterator E = params_cache.find(n);
|
||||
if (E) {
|
||||
return E->value;
|
||||
}
|
||||
}
|
||||
|
||||
if (n.begins_with("shader_parameter/")) {
|
||||
n = n.replace_first("shader_parameter/", "");
|
||||
const HashMap<StringName, StringName>::Iterator E = params_cache.find(n);
|
||||
if (E) {
|
||||
return E->value;
|
||||
}
|
||||
}
|
||||
|
||||
return StringName();
|
||||
}
|
||||
|
||||
virtual RID get_rid() const override;
|
||||
|
||||
Shader();
|
||||
|
|
Loading…
Reference in a new issue