diff --git a/doc/classes/VisualShaderNodeCubeMapUniform.xml b/doc/classes/VisualShaderNodeCubeMapUniform.xml index ad34e7d30c2..453af81009d 100644 --- a/doc/classes/VisualShaderNodeCubeMapUniform.xml +++ b/doc/classes/VisualShaderNodeCubeMapUniform.xml @@ -1,5 +1,5 @@ - + diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 58bbf862419..9e540cb87b4 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1067,7 +1067,16 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui VisualShaderNodeUniform *uniform = (VisualShaderNodeUniform *)graph[type].nodes[from_node].node.ptr(); if (uniform) { - inputs[i] = uniform->get_uniform_name(); + inputs[i] = ""; + switch (uniform->get_uniform_type()) { + case VisualShaderNodeUniform::UTYPE_CUBEMAP: + inputs[i] += "cube_"; + break; + case VisualShaderNodeUniform::UTYPE_SAMPLER2D: + inputs[i] += "s2d_"; + break; + } + inputs[i] += uniform->get_uniform_name(); } else { inputs[i] = ""; } @@ -1973,7 +1982,16 @@ void VisualShaderNodeUniform::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "uniform_name"), "set_uniform_name", "get_uniform_name"); } +int VisualShaderNodeUniform::get_uniform_type() const { + return (int)uniform_type; +} + +void VisualShaderNodeUniform::set_uniform_type(int p_type) { + uniform_type = (UniformType)p_type; +} + VisualShaderNodeUniform::VisualShaderNodeUniform() { + uniform_type = UTYPE_NONE; } ////////////// GroupBase diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 8b6b6598364..016213c3991 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -353,7 +353,16 @@ public: class VisualShaderNodeUniform : public VisualShaderNode { GDCLASS(VisualShaderNodeUniform, VisualShaderNode); +public: + enum UniformType { + UTYPE_NONE, + UTYPE_CUBEMAP, + UTYPE_SAMPLER2D, + }; + +private: String uniform_name; + UniformType uniform_type; protected: static void _bind_methods(); @@ -362,6 +371,9 @@ public: void set_uniform_name(const String &p_name); String get_uniform_name() const; + int get_uniform_type() const; + void set_uniform_type(int p_type); + VisualShaderNodeUniform(); }; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 2e58c512b86..bb42e8fb9f8 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -468,19 +468,55 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_PORT) { String id = p_input_vars[2]; + + VisualShaderNodeUniform::UniformType utype = VisualShaderNodeUniform::UTYPE_NONE; + if (id.begins_with("cube_")) { + utype = VisualShaderNodeUniform::UTYPE_CUBEMAP; + id = id.substr(5); + } else if (id.begins_with("s2d_")) { + utype = VisualShaderNodeUniform::UTYPE_SAMPLER2D; + id = id.substr(4); + } + String code; if (id == String()) { code += "\tvec4 " + id + "_tex_read = vec4(0.0);\n"; } else { if (p_input_vars[0] == String()) { // Use UV by default. - - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; - + switch (utype) { + case VisualShaderNodeUniform::UTYPE_CUBEMAP: + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , vec3(UV, 0.0) );\n"; + break; + case VisualShaderNodeUniform::UTYPE_SAMPLER2D: + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; + break; + default: + break; + } } else if (p_input_vars[1] == String()) { //no lod - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; + + switch (utype) { + case VisualShaderNodeUniform::UTYPE_CUBEMAP: + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + " );\n"; + break; + case VisualShaderNodeUniform::UTYPE_SAMPLER2D: + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; + break; + default: + break; + } } else { - code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + switch (utype) { + case VisualShaderNodeUniform::UTYPE_CUBEMAP: + code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; + break; + case VisualShaderNodeUniform::UTYPE_SAMPLER2D: + code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; + break; + default: + break; + } } code += "\t" + p_output_vars[0] + " = " + id + "_tex_read.rgb;\n"; @@ -738,7 +774,7 @@ Vector VisualShaderNodeCubeMap::get_default_t String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String u = "uniform sampler2DCube " + make_unique_id(p_type, p_id, "cube"); + String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube"); switch (texture_type) { case TYPE_DATA: break; case TYPE_COLOR: u += " : hint_albedo"; break; @@ -751,9 +787,9 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader: String id = make_unique_id(p_type, p_id, "cube"); String code; - if (p_input_vars[0] == String()) { //none bound, do nothing + if (p_input_vars[0] == String()) { // Use UV by default. - code += "\tvec4 " + id + "_read = vec4(0.0);\n"; + code += "\tvec4 " + id + "_read = texture( " + id + " , vec3(UV, 0.0) );\n"; } else if (p_input_vars[1] == String()) { //no lod @@ -767,6 +803,13 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader: return code; } +String VisualShaderNodeCubeMap::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "vec3(UV, 0.0)"; + } + return ""; +} + void VisualShaderNodeCubeMap::set_cube_map(Ref p_value) { cube_map = p_value; @@ -3205,6 +3248,7 @@ String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) c VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { texture_type = TYPE_DATA; color_default = COLOR_DEFAULT_WHITE; + set_uniform_type(VisualShaderNodeUniform::UTYPE_SAMPLER2D); } ////////////// Texture Uniform (Triplanar) @@ -3314,28 +3358,55 @@ String VisualShaderNodeCubeMapUniform::get_caption() const { return "CubeMapUniform"; } -int VisualShaderNodeCubeMapUniform::get_input_port_count() const { - return 2; -} - -VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; -} - -String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const { - return p_port == 0 ? "normal" : "lod"; -} - int VisualShaderNodeCubeMapUniform::get_output_port_count() const { - return 2; + return 1; } VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return PORT_TYPE_SAMPLER; } String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const { - return p_port == 0 ? "rgb" : "alpha"; + return "sampler"; +} + +int VisualShaderNodeCubeMapUniform::get_input_port_count() const { + return 0; +} + +VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeCubeMapUniform::get_input_port_default_hint(int p_port) const { + return ""; +} + +String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = "uniform samplerCube " + get_uniform_name(); + + switch (texture_type) { + case TYPE_DATA: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black;\n"; + else + code += ";\n"; + break; + case TYPE_COLOR: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black_albedo;\n"; + else + code += " : hint_albedo;\n"; + break; + case TYPE_NORMALMAP: code += " : hint_normal;\n"; break; + case TYPE_ANISO: code += " : hint_aniso;\n"; break; + } + + return code; } String VisualShaderNodeCubeMapUniform::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 { @@ -3343,6 +3414,7 @@ String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, Visual } VisualShaderNodeCubeMapUniform::VisualShaderNodeCubeMapUniform() { + set_uniform_type(VisualShaderNodeUniform::UTYPE_CUBEMAP); } ////////////// If diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index d5ee990191b..350e73408cd 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -277,6 +277,7 @@ public: virtual int get_input_port_count() const; virtual PortType get_input_port_type(int p_port) const; virtual String get_input_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; virtual int get_output_port_count() const; virtual PortType get_output_port_type(int p_port) const; @@ -1412,7 +1413,7 @@ public: COLOR_DEFAULT_BLACK }; -private: +protected: TextureType texture_type; ColorDefault color_default; @@ -1471,8 +1472,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeCubeMapUniform : public VisualShaderNode { - GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNode); +class VisualShaderNodeCubeMapUniform : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNodeTextureUniform); public: virtual String get_caption() const; @@ -1485,6 +1486,8 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; 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; //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 VisualShaderNodeCubeMapUniform();