Allow using integer varyings with flat interpolation modifier

This commit is contained in:
Yuri Rubinsky 2022-08-24 12:41:42 +03:00
parent d0a2a4c981
commit d4a10e7e04
5 changed files with 61 additions and 71 deletions

View File

@ -206,17 +206,19 @@
</constant> </constant>
<constant name="VARYING_TYPE_FLOAT" value="0" enum="VaryingType"> <constant name="VARYING_TYPE_FLOAT" value="0" enum="VaryingType">
</constant> </constant>
<constant name="VARYING_TYPE_VECTOR_2D" value="1" enum="VaryingType"> <constant name="VARYING_TYPE_INT" value="1" enum="VaryingType">
</constant> </constant>
<constant name="VARYING_TYPE_VECTOR_3D" value="2" enum="VaryingType"> <constant name="VARYING_TYPE_VECTOR_2D" value="2" enum="VaryingType">
</constant> </constant>
<constant name="VARYING_TYPE_VECTOR_4D" value="3" enum="VaryingType"> <constant name="VARYING_TYPE_VECTOR_3D" value="3" enum="VaryingType">
</constant> </constant>
<constant name="VARYING_TYPE_COLOR" value="4" enum="VaryingType"> <constant name="VARYING_TYPE_VECTOR_4D" value="4" enum="VaryingType">
</constant> </constant>
<constant name="VARYING_TYPE_TRANSFORM" value="5" enum="VaryingType"> <constant name="VARYING_TYPE_BOOLEAN" value="5" enum="VaryingType">
</constant> </constant>
<constant name="VARYING_TYPE_MAX" value="6" enum="VaryingType"> <constant name="VARYING_TYPE_TRANSFORM" value="6" enum="VaryingType">
</constant>
<constant name="VARYING_TYPE_MAX" value="7" enum="VaryingType">
</constant> </constant>
<constant name="NODE_ID_INVALID" value="-1"> <constant name="NODE_ID_INVALID" value="-1">
</constant> </constant>

View File

@ -4312,6 +4312,9 @@ void VisualShaderEditor::_update_varying_tree() {
case VisualShader::VARYING_TYPE_FLOAT: case VisualShader::VARYING_TYPE_FLOAT:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons"))); item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")));
break; break;
case VisualShader::VARYING_TYPE_INT:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")));
break;
case VisualShader::VARYING_TYPE_VECTOR_2D: case VisualShader::VARYING_TYPE_VECTOR_2D:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons"))); item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")));
break; break;
@ -4321,8 +4324,8 @@ void VisualShaderEditor::_update_varying_tree() {
case VisualShader::VARYING_TYPE_VECTOR_4D: case VisualShader::VARYING_TYPE_VECTOR_4D:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons"))); item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")));
break; break;
case VisualShader::VARYING_TYPE_COLOR: case VisualShader::VARYING_TYPE_BOOLEAN:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Color"), SNAME("EditorIcons"))); item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")));
break; break;
case VisualShader::VARYING_TYPE_TRANSFORM: case VisualShader::VARYING_TYPE_TRANSFORM:
item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons"))); item->set_icon(0, EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")));
@ -4963,10 +4966,11 @@ VisualShaderEditor::VisualShaderEditor() {
varying_type = memnew(OptionButton); varying_type = memnew(OptionButton);
hb->add_child(varying_type); hb->add_child(varying_type);
varying_type->add_item("Float"); varying_type->add_item("Float");
varying_type->add_item("Int");
varying_type->add_item("Vector2"); varying_type->add_item("Vector2");
varying_type->add_item("Vector3"); varying_type->add_item("Vector3");
varying_type->add_item("Vector4"); varying_type->add_item("Vector4");
varying_type->add_item("Color"); varying_type->add_item("Boolean");
varying_type->add_item("Transform"); varying_type->add_item("Transform");
varying_name = memnew(LineEdit); varying_name = memnew(LineEdit);
@ -5759,10 +5763,11 @@ public:
Ref<Texture2D> type_icon[] = { Ref<Texture2D> type_icon[] = {
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")), EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("float"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("int"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")), EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector2"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")), EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector3"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")), EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Vector4"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Color"), SNAME("EditorIcons")), EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("bool"), SNAME("EditorIcons")),
EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")), EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Transform3D"), SNAME("EditorIcons")),
}; };

View File

@ -2214,6 +2214,12 @@ void VisualShader::_update_shader() const {
case VaryingType::VARYING_TYPE_FLOAT: case VaryingType::VARYING_TYPE_FLOAT:
global_code += "float "; global_code += "float ";
break; break;
case VaryingType::VARYING_TYPE_INT:
if (E.value.mode == VaryingMode::VARYING_MODE_VERTEX_TO_FRAG_LIGHT) {
global_code += "flat ";
}
global_code += "int ";
break;
case VaryingType::VARYING_TYPE_VECTOR_2D: case VaryingType::VARYING_TYPE_VECTOR_2D:
global_code += "vec2 "; global_code += "vec2 ";
break; break;
@ -2223,8 +2229,11 @@ void VisualShader::_update_shader() const {
case VaryingType::VARYING_TYPE_VECTOR_4D: case VaryingType::VARYING_TYPE_VECTOR_4D:
global_code += "vec4 "; global_code += "vec4 ";
break; break;
case VaryingType::VARYING_TYPE_COLOR: case VaryingType::VARYING_TYPE_BOOLEAN:
global_code += "vec4 "; if (E.value.mode == VaryingMode::VARYING_MODE_VERTEX_TO_FRAG_LIGHT) {
global_code += "flat ";
}
global_code += "bool ";
break; break;
case VaryingType::VARYING_TYPE_TRANSFORM: case VaryingType::VARYING_TYPE_TRANSFORM:
global_code += "mat4 "; global_code += "mat4 ";
@ -2277,6 +2286,9 @@ void VisualShader::_update_shader() const {
case VaryingType::VARYING_TYPE_FLOAT: case VaryingType::VARYING_TYPE_FLOAT:
code2 += "0.0"; code2 += "0.0";
break; break;
case VaryingType::VARYING_TYPE_INT:
code2 += "0";
break;
case VaryingType::VARYING_TYPE_VECTOR_2D: case VaryingType::VARYING_TYPE_VECTOR_2D:
code2 += "vec2(0.0)"; code2 += "vec2(0.0)";
break; break;
@ -2286,8 +2298,8 @@ void VisualShader::_update_shader() const {
case VaryingType::VARYING_TYPE_VECTOR_4D: case VaryingType::VARYING_TYPE_VECTOR_4D:
code2 += "vec4(0.0)"; code2 += "vec4(0.0)";
break; break;
case VaryingType::VARYING_TYPE_COLOR: case VaryingType::VARYING_TYPE_BOOLEAN:
code2 += "vec4(0.0)"; code2 += "false";
break; break;
case VaryingType::VARYING_TYPE_TRANSFORM: case VaryingType::VARYING_TYPE_TRANSFORM:
code2 += "mat4(1.0)"; code2 += "mat4(1.0)";
@ -2585,10 +2597,11 @@ void VisualShader::_bind_methods() {
BIND_ENUM_CONSTANT(VARYING_MODE_MAX); BIND_ENUM_CONSTANT(VARYING_MODE_MAX);
BIND_ENUM_CONSTANT(VARYING_TYPE_FLOAT); BIND_ENUM_CONSTANT(VARYING_TYPE_FLOAT);
BIND_ENUM_CONSTANT(VARYING_TYPE_INT);
BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_2D); BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_2D);
BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_3D); BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_3D);
BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_4D); BIND_ENUM_CONSTANT(VARYING_TYPE_VECTOR_4D);
BIND_ENUM_CONSTANT(VARYING_TYPE_COLOR); BIND_ENUM_CONSTANT(VARYING_TYPE_BOOLEAN);
BIND_ENUM_CONSTANT(VARYING_TYPE_TRANSFORM); BIND_ENUM_CONSTANT(VARYING_TYPE_TRANSFORM);
BIND_ENUM_CONSTANT(VARYING_TYPE_MAX); BIND_ENUM_CONSTANT(VARYING_TYPE_MAX);
@ -4632,21 +4645,23 @@ void VisualShaderNodeVarying::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_varying_type"), &VisualShaderNodeVarying::get_varying_type); ClassDB::bind_method(D_METHOD("get_varying_type"), &VisualShaderNodeVarying::get_varying_type);
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "varying_name"), "set_varying_name", "get_varying_name"); ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "varying_name"), "set_varying_name", "get_varying_name");
ADD_PROPERTY(PropertyInfo(Variant::INT, "varying_type", PROPERTY_HINT_ENUM, "Float,Vector,Transform"), "set_varying_type", "get_varying_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "varying_type", PROPERTY_HINT_ENUM, "Float,Int,Vector2,Vector3,Vector4,Boolean,Transform"), "set_varying_type", "get_varying_type");
} }
String VisualShaderNodeVarying::get_type_str() const { String VisualShaderNodeVarying::get_type_str() const {
switch (varying_type) { switch (varying_type) {
case VisualShader::VARYING_TYPE_FLOAT: case VisualShader::VARYING_TYPE_FLOAT:
return "float"; return "float";
case VisualShader::VARYING_TYPE_INT:
return "int";
case VisualShader::VARYING_TYPE_VECTOR_2D: case VisualShader::VARYING_TYPE_VECTOR_2D:
return "vec2"; return "vec2";
case VisualShader::VARYING_TYPE_VECTOR_3D: case VisualShader::VARYING_TYPE_VECTOR_3D:
return "vec3"; return "vec3";
case VisualShader::VARYING_TYPE_VECTOR_4D: case VisualShader::VARYING_TYPE_VECTOR_4D:
return "vec4"; return "vec4";
case VisualShader::VARYING_TYPE_COLOR: case VisualShader::VARYING_TYPE_BOOLEAN:
return "vec4"; return "bool";
case VisualShader::VARYING_TYPE_TRANSFORM: case VisualShader::VARYING_TYPE_TRANSFORM:
return "mat4"; return "mat4";
default: default:
@ -4657,17 +4672,16 @@ String VisualShaderNodeVarying::get_type_str() const {
VisualShaderNodeVarying::PortType VisualShaderNodeVarying::get_port_type(VisualShader::VaryingType p_type, int p_port) const { VisualShaderNodeVarying::PortType VisualShaderNodeVarying::get_port_type(VisualShader::VaryingType p_type, int p_port) const {
switch (p_type) { switch (p_type) {
case VisualShader::VARYING_TYPE_INT:
return PORT_TYPE_SCALAR_INT;
case VisualShader::VARYING_TYPE_VECTOR_2D: case VisualShader::VARYING_TYPE_VECTOR_2D:
return PORT_TYPE_VECTOR_2D; return PORT_TYPE_VECTOR_2D;
case VisualShader::VARYING_TYPE_VECTOR_3D: case VisualShader::VARYING_TYPE_VECTOR_3D:
return PORT_TYPE_VECTOR_3D; return PORT_TYPE_VECTOR_3D;
case VisualShader::VARYING_TYPE_VECTOR_4D: case VisualShader::VARYING_TYPE_VECTOR_4D:
return PORT_TYPE_VECTOR_4D; return PORT_TYPE_VECTOR_4D;
case VisualShader::VARYING_TYPE_COLOR: case VisualShader::VARYING_TYPE_BOOLEAN:
if (p_port == 1) { return PORT_TYPE_BOOLEAN;
break; // scalar
}
return PORT_TYPE_VECTOR_3D;
case VisualShader::VARYING_TYPE_TRANSFORM: case VisualShader::VARYING_TYPE_TRANSFORM:
return PORT_TYPE_TRANSFORM; return PORT_TYPE_TRANSFORM;
default: default:
@ -4711,9 +4725,6 @@ String VisualShaderNodeVaryingSetter::get_caption() const {
} }
int VisualShaderNodeVaryingSetter::get_input_port_count() const { int VisualShaderNodeVaryingSetter::get_input_port_count() const {
if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
return 2;
}
return 1; return 1;
} }
@ -4722,13 +4733,6 @@ VisualShaderNodeVaryingSetter::PortType VisualShaderNodeVaryingSetter::get_input
} }
String VisualShaderNodeVaryingSetter::get_input_port_name(int p_port) const { String VisualShaderNodeVaryingSetter::get_input_port_name(int p_port) const {
if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
if (p_port == 0) {
return "color";
} else {
return "alpha";
}
}
return ""; return "";
} }
@ -4744,20 +4748,12 @@ String VisualShaderNodeVaryingSetter::get_output_port_name(int p_port) const {
return ""; return "";
} }
String VisualShaderNodeVaryingSetter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return vformat("varying %s %s;\n", get_type_str(), varying_name);
}
String VisualShaderNodeVaryingSetter::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 VisualShaderNodeVaryingSetter::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 code; String code;
if (varying_name == "[None]") { if (varying_name == "[None]") {
return code; return code;
} }
if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
code += vformat(" %s = vec4(%s, %s);\n", varying_name, p_input_vars[0], p_input_vars[1]);
} else {
code += vformat(" %s = %s;\n", varying_name, p_input_vars[0]); code += vformat(" %s = %s;\n", varying_name, p_input_vars[0]);
}
return code; return code;
} }
@ -4783,9 +4779,6 @@ String VisualShaderNodeVaryingGetter::get_input_port_name(int p_port) const {
} }
int VisualShaderNodeVaryingGetter::get_output_port_count() const { int VisualShaderNodeVaryingGetter::get_output_port_count() const {
if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
return 2;
}
return 1; return 1;
} }
@ -4794,13 +4787,6 @@ VisualShaderNodeVaryingGetter::PortType VisualShaderNodeVaryingGetter::get_outpu
} }
String VisualShaderNodeVaryingGetter::get_output_port_name(int p_port) const { String VisualShaderNodeVaryingGetter::get_output_port_name(int p_port) const {
if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
if (p_port == 0) {
return "color";
} else {
return "alpha";
}
}
return ""; return "";
} }
@ -4817,6 +4803,9 @@ String VisualShaderNodeVaryingGetter::generate_code(Shader::Mode p_mode, VisualS
case VisualShader::VARYING_TYPE_FLOAT: case VisualShader::VARYING_TYPE_FLOAT:
from = "0.0"; from = "0.0";
break; break;
case VisualShader::VARYING_TYPE_INT:
from = "0";
break;
case VisualShader::VARYING_TYPE_VECTOR_2D: case VisualShader::VARYING_TYPE_VECTOR_2D:
from = "vec2(0.0)"; from = "vec2(0.0)";
break; break;
@ -4826,9 +4815,8 @@ String VisualShaderNodeVaryingGetter::generate_code(Shader::Mode p_mode, VisualS
case VisualShader::VARYING_TYPE_VECTOR_4D: case VisualShader::VARYING_TYPE_VECTOR_4D:
from = "vec4(0.0)"; from = "vec4(0.0)";
break; break;
case VisualShader::VARYING_TYPE_COLOR: case VisualShader::VARYING_TYPE_BOOLEAN:
from = "vec3(0.0)"; from = "false";
from2 = "0.0";
break; break;
case VisualShader::VARYING_TYPE_TRANSFORM: case VisualShader::VARYING_TYPE_TRANSFORM:
from = "mat4(1.0)"; from = "mat4(1.0)";
@ -4836,16 +4824,6 @@ String VisualShaderNodeVaryingGetter::generate_code(Shader::Mode p_mode, VisualS
default: default:
break; break;
} }
} else if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
from = varying_name + ".rgb";
from2 = varying_name + ".a";
}
if (varying_type == VisualShader::VARYING_TYPE_COLOR) {
String code;
code += vformat(" %s = %s;\n", p_output_vars[0], from);
code += vformat(" %s = %s;\n", p_output_vars[1], from2);
return code;
} }
return vformat(" %s = %s;\n", p_output_vars[0], from); return vformat(" %s = %s;\n", p_output_vars[0], from);
} }

View File

@ -79,10 +79,11 @@ public:
enum VaryingType { enum VaryingType {
VARYING_TYPE_FLOAT, VARYING_TYPE_FLOAT,
VARYING_TYPE_INT,
VARYING_TYPE_VECTOR_2D, VARYING_TYPE_VECTOR_2D,
VARYING_TYPE_VECTOR_3D, VARYING_TYPE_VECTOR_3D,
VARYING_TYPE_VECTOR_4D, VARYING_TYPE_VECTOR_4D,
VARYING_TYPE_COLOR, VARYING_TYPE_BOOLEAN,
VARYING_TYPE_TRANSFORM, VARYING_TYPE_TRANSFORM,
VARYING_TYPE_MAX, VARYING_TYPE_MAX,
}; };
@ -828,7 +829,6 @@ public:
virtual PortType get_output_port_type(int p_port) const override; virtual PortType get_output_port_type(int p_port) const override;
virtual String get_output_port_name(int p_port) const override; virtual String get_output_port_name(int p_port) 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; 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;
VisualShaderNodeVaryingSetter(); VisualShaderNodeVaryingSetter();

View File

@ -5377,6 +5377,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} }
_set_tkpos(prev_pos); _set_tkpos(prev_pos);
ShaderNode::Varying &var = shader->varyings[identifier];
String error; String error;
if (is_token_operator_assign(next_token.type)) { if (is_token_operator_assign(next_token.type)) {
if (!_validate_varying_assign(shader->varyings[identifier], &error)) { if (!_validate_varying_assign(shader->varyings[identifier], &error)) {
@ -5384,8 +5385,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr; return nullptr;
} }
} else { } else {
ShaderNode::Varying &var = shader->varyings[identifier];
switch (var.stage) { switch (var.stage) {
case ShaderNode::Varying::STAGE_VERTEX: case ShaderNode::Varying::STAGE_VERTEX:
if (current_function == varying_function_names.fragment || current_function == varying_function_names.light) { if (current_function == varying_function_names.fragment || current_function == varying_function_names.light) {
@ -5401,6 +5400,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
break; break;
} }
} }
if ((var.stage != ShaderNode::Varying::STAGE_FRAGMENT && var.stage != ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT) && var.type < TYPE_FLOAT && var.interpolation != INTERPOLATION_FLAT) {
_set_tkpos(var.tkpos);
_set_error(RTR("Varying with integer data type must be declared with `flat` interpolation qualifier."));
return nullptr;
}
} }
if (ident_type == IDENTIFIER_FUNCTION) { if (ident_type == IDENTIFIER_FUNCTION) {
@ -8299,8 +8304,8 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }
if (!is_uniform && (type < TYPE_FLOAT || type > TYPE_MAT4)) { if (!is_uniform && type > TYPE_MAT4) {
_set_error(RTR("Invalid type for varying, only 'float', 'vec2', 'vec3', 'vec4', 'mat2', 'mat3', 'mat4', or arrays of these types are allowed.")); _set_error(RTR("Invalid data type for varying."));
return ERR_PARSE_ERROR; return ERR_PARSE_ERROR;
} }