Merge pull request #71797 from reduz/cleanup-shader-parameter-remap
Clean up shader parameter remap
This commit is contained in:
commit
145ab2e1fd
@ -26,12 +26,12 @@
|
|||||||
Returns the shader mode for the shader, either [constant MODE_CANVAS_ITEM], [constant MODE_SPATIAL] or [constant MODE_PARTICLES].
|
Returns the shader mode for the shader, either [constant MODE_CANVAS_ITEM], [constant MODE_SPATIAL] or [constant MODE_PARTICLES].
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="has_parameter" qualifiers="const">
|
<method name="get_shader_uniform_list">
|
||||||
<return type="bool" />
|
<return type="Array" />
|
||||||
<param index="0" name="name" type="StringName" />
|
<param index="0" name="get_groups" type="bool" default="false" />
|
||||||
<description>
|
<description>
|
||||||
Returns [code]true[/code] if the shader has this param defined as a uniform in its code.
|
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].
|
||||||
[b]Note:[/b] [param name] must match the name of the uniform in the code exactly.
|
If argument [param get_groups] is true, parameter grouping hints will be provided.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="set_default_texture_parameter">
|
<method name="set_default_texture_parameter">
|
||||||
|
@ -149,11 +149,36 @@ Material::~Material() {
|
|||||||
|
|
||||||
bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
|
bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
|
||||||
if (shader.is_valid()) {
|
if (shader.is_valid()) {
|
||||||
StringName pr = shader->remap_parameter(p_name);
|
const StringName *sn = remap_cache.getptr(p_name);
|
||||||
if (pr) {
|
if (sn) {
|
||||||
set_shader_parameter(pr, p_value);
|
set_shader_parameter(*sn, p_value);
|
||||||
return true;
|
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;
|
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 {
|
bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
|
||||||
if (shader.is_valid()) {
|
if (shader.is_valid()) {
|
||||||
StringName pr = shader->remap_parameter(p_name);
|
const StringName *sn = remap_cache.getptr(p_name);
|
||||||
if (pr) {
|
if (sn) {
|
||||||
r_ret = get_shader_parameter(pr);
|
// Only return a parameter if it was previosly set.
|
||||||
|
r_ret = get_shader_parameter(*sn);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -247,6 +273,12 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||||||
|
|
||||||
PropertyInfo info = E->get();
|
PropertyInfo info = E->get();
|
||||||
info.name = "shader_parameter/" + info.name;
|
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);
|
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 {
|
bool ShaderMaterial::_property_can_revert(const StringName &p_name) const {
|
||||||
if (shader.is_valid()) {
|
if (shader.is_valid()) {
|
||||||
StringName pr = shader->remap_parameter(p_name);
|
const StringName *pr = remap_cache.getptr(p_name);
|
||||||
if (pr) {
|
if (pr) {
|
||||||
Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr);
|
Variant default_value = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr);
|
||||||
Variant current_value;
|
Variant current_value = get_shader_parameter(*pr);
|
||||||
_get(p_name, current_value);
|
|
||||||
return default_value.get_type() != Variant::NIL && default_value != current_value;
|
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 {
|
bool ShaderMaterial::_property_get_revert(const StringName &p_name, Variant &r_property) const {
|
||||||
if (shader.is_valid()) {
|
if (shader.is_valid()) {
|
||||||
StringName pr = shader->remap_parameter(p_name);
|
const StringName *pr = remap_cache.getptr(p_name);
|
||||||
if (pr) {
|
if (*pr) {
|
||||||
r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), pr);
|
r_property = RenderingServer::get_singleton()->shader_get_parameter_default(shader->get_rid(), *pr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,8 @@ class ShaderMaterial : public Material {
|
|||||||
GDCLASS(ShaderMaterial, Material);
|
GDCLASS(ShaderMaterial, Material);
|
||||||
Ref<Shader> shader;
|
Ref<Shader> shader;
|
||||||
|
|
||||||
HashMap<StringName, Variant> param_cache;
|
mutable HashMap<StringName, StringName> remap_cache;
|
||||||
|
mutable HashMap<StringName, Variant> param_cache;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool _set(const StringName &p_name, const Variant &p_value);
|
bool _set(const StringName &p_name, const Variant &p_value);
|
||||||
|
@ -43,7 +43,6 @@ Shader::Mode Shader::get_mode() const {
|
|||||||
|
|
||||||
void Shader::_dependency_changed() {
|
void Shader::_dependency_changed() {
|
||||||
RenderingServer::get_singleton()->shader_set_code(shader, RenderingServer::get_singleton()->shader_get_code(shader));
|
RenderingServer::get_singleton()->shader_set_code(shader, RenderingServer::get_singleton()->shader_get_code(shader));
|
||||||
params_cache_dirty = true;
|
|
||||||
|
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
@ -93,7 +92,6 @@ void Shader::set_code(const String &p_code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
RenderingServer::get_singleton()->shader_set_code(shader, pp_code);
|
RenderingServer::get_singleton()->shader_set_code(shader, pp_code);
|
||||||
params_cache_dirty = true;
|
|
||||||
|
|
||||||
emit_changed();
|
emit_changed();
|
||||||
}
|
}
|
||||||
@ -108,8 +106,6 @@ void Shader::get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_gr
|
|||||||
|
|
||||||
List<PropertyInfo> local;
|
List<PropertyInfo> local;
|
||||||
RenderingServer::get_singleton()->get_shader_parameter_list(shader, &local);
|
RenderingServer::get_singleton()->get_shader_parameter_list(shader, &local);
|
||||||
params_cache.clear();
|
|
||||||
params_cache_dirty = false;
|
|
||||||
|
|
||||||
for (PropertyInfo &pi : local) {
|
for (PropertyInfo &pi : local) {
|
||||||
bool is_group = pi.usage == PROPERTY_USAGE_GROUP || pi.usage == PROPERTY_USAGE_SUBGROUP;
|
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
|
if (default_textures.has(pi.name)) { //do not show default textures
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
params_cache[pi.name] = pi.name;
|
|
||||||
}
|
}
|
||||||
if (p_params) {
|
if (p_params) {
|
||||||
//small little hack
|
//small little hack
|
||||||
@ -176,11 +171,17 @@ bool Shader::is_text_shader() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Shader::has_parameter(const StringName &p_name) const {
|
void Shader::_update_shader() const {
|
||||||
return params_cache.has(p_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
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("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("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");
|
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;
|
HashSet<Ref<ShaderInclude>> include_dependencies;
|
||||||
String code;
|
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;
|
HashMap<StringName, HashMap<int, Ref<Texture2D>>> default_textures;
|
||||||
|
|
||||||
void _dependency_changed();
|
void _dependency_changed();
|
||||||
virtual void _update_shader() const; //used for visual shader
|
virtual void _update_shader() const; //used for visual shader
|
||||||
|
Array _get_shader_uniform_list(bool p_get_groups = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
@ -79,7 +76,6 @@ public:
|
|||||||
String get_code() const;
|
String get_code() const;
|
||||||
|
|
||||||
void get_shader_uniform_list(List<PropertyInfo> *p_params, bool p_get_groups = false) 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);
|
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;
|
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;
|
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;
|
virtual RID get_rid() const override;
|
||||||
|
|
||||||
Shader();
|
Shader();
|
||||||
|
Loading…
Reference in New Issue
Block a user