Browse Source

Add `hint_color` support for `vec3` in shaders

Yuri Roubinsky 3 years ago
parent
commit
5eb3a0ef4a

+ 51 - 17
drivers/gles3/storage/material_storage.cpp

@@ -392,26 +392,60 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
 			float *gui = (float *)data;
 			float *gui = (float *)data;
 
 
 			if (p_array_size > 0) {
 			if (p_array_size > 0) {
-				const PackedVector3Array &a = value;
-				int s = a.size();
+				if (value.get_type() == Variant::PACKED_COLOR_ARRAY) {
+					const PackedColorArray &a = value;
+					int s = a.size();
 
 
-				for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
-					if (i < s) {
-						gui[j] = a[i].x;
-						gui[j + 1] = a[i].y;
-						gui[j + 2] = a[i].z;
-					} else {
-						gui[j] = 0;
-						gui[j + 1] = 0;
-						gui[j + 2] = 0;
+					for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
+						if (i < s) {
+							Color color = a[i];
+							if (p_linear_color) {
+								color = color.srgb_to_linear();
+							}
+							gui[j] = color.r;
+							gui[j + 1] = color.g;
+							gui[j + 2] = color.b;
+						} else {
+							gui[j] = 0;
+							gui[j + 1] = 0;
+							gui[j + 2] = 0;
+						}
+						gui[j + 3] = 0; // ignored
+					}
+				} else {
+					const PackedVector3Array &a = value;
+					int s = a.size();
+
+					for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
+						if (i < s) {
+							gui[j] = a[i].x;
+							gui[j + 1] = a[i].y;
+							gui[j + 2] = a[i].z;
+						} else {
+							gui[j] = 0;
+							gui[j + 1] = 0;
+							gui[j + 2] = 0;
+						}
+						gui[j + 3] = 0; // ignored
 					}
 					}
-					gui[j + 3] = 0; // ignored
 				}
 				}
 			} else {
 			} else {
-				Vector3 v = value;
-				gui[0] = v.x;
-				gui[1] = v.y;
-				gui[2] = v.z;
+				if (value.get_type() == Variant::COLOR) {
+					Color v = value;
+
+					if (p_linear_color) {
+						v = v.srgb_to_linear();
+					}
+
+					gui[0] = v.r;
+					gui[1] = v.g;
+					gui[2] = v.b;
+				} else {
+					Vector3 v = value;
+					gui[0] = v.x;
+					gui[1] = v.y;
+					gui[2] = v.z;
+				}
 			}
 			}
 		} break;
 		} break;
 		case ShaderLanguage::TYPE_VEC4: {
 		case ShaderLanguage::TYPE_VEC4: {
@@ -925,7 +959,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
 			//value=E.value.default_value;
 			//value=E.value.default_value;
 		} else {
 		} else {
 			//zero because it was not provided
 			//zero because it was not provided
-			if (E.value.type == ShaderLanguage::TYPE_VEC4 && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+			if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
 				//colors must be set as black, with alpha as 1.0
 				//colors must be set as black, with alpha as 1.0
 				_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
 				_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
 			} else {
 			} else {

+ 51 - 17
servers/rendering/renderer_rd/storage_rd/material_storage.cpp

@@ -388,26 +388,60 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
 			float *gui = reinterpret_cast<float *>(data);
 			float *gui = reinterpret_cast<float *>(data);
 
 
 			if (p_array_size > 0) {
 			if (p_array_size > 0) {
-				const PackedVector3Array &a = value;
-				int s = a.size();
+				if (value.get_type() == Variant::PACKED_COLOR_ARRAY) {
+					const PackedColorArray &a = value;
+					int s = a.size();
 
 
-				for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
-					if (i < s) {
-						gui[j] = a[i].x;
-						gui[j + 1] = a[i].y;
-						gui[j + 2] = a[i].z;
-					} else {
-						gui[j] = 0;
-						gui[j + 1] = 0;
-						gui[j + 2] = 0;
+					for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
+						if (i < s) {
+							Color color = a[i];
+							if (p_linear_color) {
+								color = color.srgb_to_linear();
+							}
+							gui[j] = color.r;
+							gui[j + 1] = color.g;
+							gui[j + 2] = color.b;
+						} else {
+							gui[j] = 0;
+							gui[j + 1] = 0;
+							gui[j + 2] = 0;
+						}
+						gui[j + 3] = 0; // ignored
+					}
+				} else {
+					const PackedVector3Array &a = value;
+					int s = a.size();
+
+					for (int i = 0, j = 0; i < p_array_size; i++, j += 4) {
+						if (i < s) {
+							gui[j] = a[i].x;
+							gui[j + 1] = a[i].y;
+							gui[j + 2] = a[i].z;
+						} else {
+							gui[j] = 0;
+							gui[j + 1] = 0;
+							gui[j + 2] = 0;
+						}
+						gui[j + 3] = 0; // ignored
 					}
 					}
-					gui[j + 3] = 0; // ignored
 				}
 				}
 			} else {
 			} else {
-				Vector3 v = value;
-				gui[0] = v.x;
-				gui[1] = v.y;
-				gui[2] = v.z;
+				if (value.get_type() == Variant::COLOR) {
+					Color v = value;
+
+					if (p_linear_color) {
+						v = v.srgb_to_linear();
+					}
+
+					gui[0] = v.r;
+					gui[1] = v.g;
+					gui[2] = v.b;
+				} else {
+					Vector3 v = value;
+					gui[0] = v.x;
+					gui[1] = v.y;
+					gui[2] = v.z;
+				}
 			}
 			}
 		} break;
 		} break;
 		case ShaderLanguage::TYPE_VEC4: {
 		case ShaderLanguage::TYPE_VEC4: {
@@ -921,7 +955,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S
 			//value=E.value.default_value;
 			//value=E.value.default_value;
 		} else {
 		} else {
 			//zero because it was not provided
 			//zero because it was not provided
-			if (E.value.type == ShaderLanguage::TYPE_VEC4 && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+			if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
 				//colors must be set as black, with alpha as 1.0
 				//colors must be set as black, with alpha as 1.0
 				_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
 				_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color);
 			} else {
 			} else {

+ 32 - 10
servers/rendering/shader_language.cpp

@@ -3548,13 +3548,25 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
 				if (array_size > 0) {
 				if (array_size > 0) {
 					array_size *= 3;
 					array_size *= 3;
 
 
-					PackedVector3Array array = PackedVector3Array();
-					for (int i = 0; i < array_size; i += 3) {
-						array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
+					if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+						PackedColorArray array = PackedColorArray();
+						for (int i = 0; i < array_size; i += 3) {
+							array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
+						}
+						value = Variant(array);
+					} else {
+						PackedVector3Array array = PackedVector3Array();
+						for (int i = 0; i < array_size; i += 3) {
+							array.push_back(Vector3(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real));
+						}
+						value = Variant(array);
 					}
 					}
-					value = Variant(array);
 				} else {
 				} else {
-					value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
+					if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+						value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real));
+					} else {
+						value = Variant(Vector3(p_value[0].real, p_value[1].real, p_value[2].real));
+					}
 				}
 				}
 				break;
 				break;
 			case ShaderLanguage::TYPE_VEC4:
 			case ShaderLanguage::TYPE_VEC4:
@@ -3760,9 +3772,19 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
 			break;
 			break;
 		case ShaderLanguage::TYPE_VEC3:
 		case ShaderLanguage::TYPE_VEC3:
 			if (p_uniform.array_size > 0) {
 			if (p_uniform.array_size > 0) {
-				pi.type = Variant::PACKED_VECTOR3_ARRAY;
+				if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+					pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
+					pi.type = Variant::PACKED_COLOR_ARRAY;
+				} else {
+					pi.type = Variant::PACKED_VECTOR3_ARRAY;
+				}
 			} else {
 			} else {
-				pi.type = Variant::VECTOR3;
+				if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
+					pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
+					pi.type = Variant::COLOR;
+				} else {
+					pi.type = Variant::VECTOR3;
+				}
 			}
 			}
 			break;
 			break;
 		case ShaderLanguage::TYPE_VEC4: {
 		case ShaderLanguage::TYPE_VEC4: {
@@ -8001,8 +8023,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
 							} else if (tk.type == TK_HINT_BLACK_ALBEDO_TEXTURE) {
 							} else if (tk.type == TK_HINT_BLACK_ALBEDO_TEXTURE) {
 								uniform2.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO;
 								uniform2.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO;
 							} else if (tk.type == TK_HINT_COLOR) {
 							} else if (tk.type == TK_HINT_COLOR) {
-								if (type != TYPE_VEC4) {
-									_set_error(vformat(RTR("Color hint is for '%s' only."), "vec4"));
+								if (type != TYPE_VEC3 && type != TYPE_VEC4) {
+									_set_error(vformat(RTR("Color hint is for '%s' or '%s' only."), "vec3", "vec4"));
 									return ERR_PARSE_ERROR;
 									return ERR_PARSE_ERROR;
 								}
 								}
 								uniform2.hint = ShaderNode::Uniform::HINT_COLOR;
 								uniform2.hint = ShaderNode::Uniform::HINT_COLOR;
@@ -9514,7 +9536,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
 
 
 		} break;
 		} break;
 		case COMPLETION_HINT: {
 		case COMPLETION_HINT: {
-			if (completion_base == DataType::TYPE_VEC4) {
+			if (completion_base == DataType::TYPE_VEC3 || completion_base == DataType::TYPE_VEC4) {
 				ScriptLanguage::CodeCompletionOption option("hint_color", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
 				ScriptLanguage::CodeCompletionOption option("hint_color", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT);
 				r_options->push_back(option);
 				r_options->push_back(option);
 			} else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) {
 			} else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) {