mirror of
https://github.com/godotengine/godot.git
synced 2024-11-23 12:43:43 +00:00
Allow multiple triplanar textures to be used within one visual shader
This commit is contained in:
parent
f952bfe998
commit
8e5f59500c
@ -38,6 +38,10 @@
|
||||
#include "visual_shader_particle_nodes.h"
|
||||
#include "visual_shader_sdf_nodes.h"
|
||||
|
||||
#ifdef MODULE_REGEX_ENABLED
|
||||
#include "modules/regex/regex.h"
|
||||
#endif // MODULE_REGEX_ENABLED
|
||||
|
||||
String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name) {
|
||||
static const char *typepf[VisualShader::TYPE_MAX] = { "vtx", "frg", "lgt", "start", "process", "collide", "start_custom", "process_custom", "sky", "fog" };
|
||||
return p_name + "_" + String(typepf[p_type]) + "_" + itos(p_id);
|
||||
@ -381,6 +385,10 @@ String VisualShaderNode::generate_global_per_func(Shader::Mode p_mode, VisualSha
|
||||
return String();
|
||||
}
|
||||
|
||||
String VisualShaderNode::generate_global_per_func_multi(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||
return String();
|
||||
}
|
||||
|
||||
Vector<StringName> VisualShaderNode::get_editable_properties() const {
|
||||
return Vector<StringName>();
|
||||
}
|
||||
@ -2018,6 +2026,11 @@ Error VisualShader::_write_node(Type type, StringBuilder *p_global_code, StringB
|
||||
}
|
||||
r_classes.insert(class_name);
|
||||
}
|
||||
for (int i = 0; i < TYPE_MAX; i++) {
|
||||
if (p_global_code_per_func) {
|
||||
(*p_global_code_per_func)[Type(i)] += vsnode->generate_global_per_func_multi(get_mode(), Type(i), p_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!vsnode->is_code_generated()) { // just generate globals and ignore locals
|
||||
@ -4334,6 +4347,35 @@ String VisualShaderNodeParameter::get_warning(Shader::Mode p_mode, VisualShader:
|
||||
return String();
|
||||
}
|
||||
|
||||
int VisualShaderNodeParameter::get_index() const {
|
||||
#ifdef MODULE_REGEX_ENABLED
|
||||
RegEx regex = RegEx("\\d+$");
|
||||
Ref<RegExMatch> match = regex.search(parameter_name);
|
||||
if (match.is_null()) {
|
||||
return 0;
|
||||
}
|
||||
return match->get_strings()[0].to_int();
|
||||
#else
|
||||
String buffer;
|
||||
for (int i = 0; i < parameter_name.length(); i++) {
|
||||
int index = parameter_name.length() - i - 1;
|
||||
String ch = parameter_name.substr(index, 1);
|
||||
|
||||
if (ch.is_valid_int()) {
|
||||
buffer += ch;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer.is_empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buffer.reverse().to_int();
|
||||
#endif
|
||||
}
|
||||
|
||||
Vector<StringName> VisualShaderNodeParameter::get_editable_properties() const {
|
||||
Vector<StringName> props;
|
||||
props.push_back("qualifier");
|
||||
|
@ -377,6 +377,7 @@ public:
|
||||
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
|
||||
virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const;
|
||||
virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
|
||||
virtual String generate_global_per_func_multi(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
|
||||
// If no output is connected, the output var passed will be empty. If no input is connected and input is NIL, the input var passed will be empty.
|
||||
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const = 0;
|
||||
|
||||
@ -626,6 +627,8 @@ public:
|
||||
virtual bool is_qualifier_supported(Qualifier p_qual) const = 0;
|
||||
virtual bool is_convertible_to_constant() const = 0;
|
||||
|
||||
int get_index() const;
|
||||
|
||||
virtual Vector<StringName> get_editable_properties() const override;
|
||||
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
|
||||
|
||||
|
@ -6758,34 +6758,34 @@ String VisualShaderNodeTextureParameterTriplanar::generate_global_per_node(Shade
|
||||
String code;
|
||||
|
||||
code += "// " + get_caption() + "\n";
|
||||
code += " vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n";
|
||||
code += " vec4 samp = vec4(0.0);\n";
|
||||
code += " samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n";
|
||||
code += " samp += texture(p_sampler, p_triplanar_pos.xz) * p_weights.y;\n";
|
||||
code += " samp += texture(p_sampler, p_triplanar_pos.zy * vec2(-1.0, 1.0)) * p_weights.x;\n";
|
||||
code += " return samp;\n";
|
||||
code += " }\n";
|
||||
code += "\n";
|
||||
code += " uniform vec3 triplanar_scale = vec3(1.0, 1.0, 1.0);\n";
|
||||
code += " uniform vec3 triplanar_offset;\n";
|
||||
code += " uniform float triplanar_sharpness = 0.5;\n";
|
||||
code += "\n";
|
||||
code += " varying vec3 triplanar_power_normal;\n";
|
||||
code += " varying vec3 triplanar_pos;\n";
|
||||
code += "vec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n";
|
||||
code += " vec4 samp = vec4(0.0);\n";
|
||||
code += " samp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n";
|
||||
code += " samp += texture(p_sampler, p_triplanar_pos.xz) * p_weights.y;\n";
|
||||
code += " samp += texture(p_sampler, p_triplanar_pos.zy * vec2(-1.0, 1.0)) * p_weights.x;\n";
|
||||
code += " return samp;\n";
|
||||
code += "}\n";
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
String VisualShaderNodeTextureParameterTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||
String VisualShaderNodeTextureParameterTriplanar::generate_global_per_func_multi(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||
String code;
|
||||
|
||||
if (p_type == VisualShader::TYPE_VERTEX) {
|
||||
int index = get_index();
|
||||
|
||||
String index_string;
|
||||
if (index > 0) {
|
||||
index_string = itos(index);
|
||||
}
|
||||
|
||||
code += "// " + get_caption() + "\n";
|
||||
code += " {\n";
|
||||
code += " triplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n";
|
||||
code += " triplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n";
|
||||
code += " triplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n";
|
||||
code += " triplanar_pos *= vec3(1.0, -1.0, 1.0);\n";
|
||||
code += vformat(" triplanar_power_normal%s = pow(abs(NORMAL), vec3(triplanar_sharpness%s));\n", index_string, index_string);
|
||||
code += vformat(" triplanar_power_normal%s /= dot(triplanar_power_normal%s, vec3(1.0));\n", index_string, index_string);
|
||||
code += vformat(" triplanar_pos%s = VERTEX * triplanar_scale%s + triplanar_offset%s;\n", index_string, index_string, index_string);
|
||||
code += vformat(" triplanar_pos%s *= vec3(1.0, -1.0, 1.0);\n", index_string);
|
||||
code += " }\n";
|
||||
}
|
||||
|
||||
@ -6794,21 +6794,42 @@ String VisualShaderNodeTextureParameterTriplanar::generate_global_per_func(Shade
|
||||
|
||||
String VisualShaderNodeTextureParameterTriplanar::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
|
||||
String code = _get_qual_str() + "uniform sampler2D " + get_parameter_name();
|
||||
int index = get_index();
|
||||
|
||||
code += get_sampler_hint(texture_type, color_default, texture_filter, texture_repeat, texture_source);
|
||||
code += ";\n";
|
||||
|
||||
String index_string;
|
||||
if (index > 0) {
|
||||
index_string = itos(index);
|
||||
}
|
||||
|
||||
code += vformat("uniform vec3 triplanar_scale%s = vec3(1.0, 1.0, 1.0);\n", index_string);
|
||||
code += vformat("uniform vec3 triplanar_offset%s;\n", index_string);
|
||||
code += vformat("uniform float triplanar_sharpness%s = 0.5;\n", index_string);
|
||||
code += vformat("varying vec3 triplanar_power_normal%s;\n", index_string);
|
||||
code += vformat("varying vec3 triplanar_pos%s;\n", index_string);
|
||||
code += "\n";
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
String VisualShaderNodeTextureParameterTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
|
||||
String id = get_parameter_name();
|
||||
int index = get_index();
|
||||
|
||||
String index_string;
|
||||
if (index > 0) {
|
||||
index_string = itos(index);
|
||||
}
|
||||
|
||||
String code;
|
||||
if (p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) {
|
||||
code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", triplanar_power_normal, triplanar_pos);\n";
|
||||
code += " " + p_output_vars[0] + " = triplanar_texture(" + id + vformat(", triplanar_power_normal%s, triplanar_pos%s);\n", index_string, index_string);
|
||||
} else if (!p_input_vars[0].is_empty() && p_input_vars[1].is_empty()) {
|
||||
code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", " + p_input_vars[0] + ", triplanar_pos);\n";
|
||||
code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", " + p_input_vars[0] + vformat(", triplanar_pos%s);\n", index_string);
|
||||
} else if (p_input_vars[0].is_empty() && !p_input_vars[1].is_empty()) {
|
||||
code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", triplanar_power_normal, " + p_input_vars[1] + ");\n";
|
||||
code += " " + p_output_vars[0] + " = triplanar_texture(" + id + vformat(", triplanar_power_normal%s, ", index_string) + p_input_vars[1] + ");\n";
|
||||
} else {
|
||||
code += " " + p_output_vars[0] + " = triplanar_texture(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
|
||||
}
|
||||
|
@ -2625,7 +2625,7 @@ public:
|
||||
virtual bool is_input_port_default(int p_port, Shader::Mode p_mode) const override;
|
||||
|
||||
virtual String generate_global_per_node(Shader::Mode p_mode, int p_id) const override;
|
||||
virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
|
||||
virtual String generate_global_per_func_multi(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
|
||||
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override;
|
||||
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user