diff options
author | Yuri Roubinsky <chaosus89@gmail.com> | 2022-05-01 09:47:35 +0300 |
---|---|---|
committer | Yuri Roubinsky <chaosus89@gmail.com> | 2022-05-01 09:47:35 +0300 |
commit | 5eb3a0ef4a60330edb377337ec487e899e5352bc (patch) | |
tree | a404ec6192b45f54b809fa2eaeeb7e7e76df7175 /servers/rendering | |
parent | 4a9e8b560a648f4c1746697b348ebbbb89c5bb0a (diff) |
Add `hint_color` support for `vec3` in shaders
Diffstat (limited to 'servers/rendering')
-rw-r--r-- | servers/rendering/renderer_rd/storage_rd/material_storage.cpp | 68 | ||||
-rw-r--r-- | servers/rendering/shader_language.cpp | 42 |
2 files changed, 83 insertions, 27 deletions
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index d939a0d641..c3747ffabc 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/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); 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 { - 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; case ShaderLanguage::TYPE_VEC4: { @@ -921,7 +955,7 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S //value=E.value.default_value; } else { //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 _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, p_use_linear_color); } else { diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 54d1a6fd8d..1fd7062d6e 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -3548,13 +3548,25 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C if (array_size > 0) { 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 { - 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; case ShaderLanguage::TYPE_VEC4: @@ -3760,9 +3772,19 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform break; case ShaderLanguage::TYPE_VEC3: 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 { - 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; 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) { uniform2.hint = ShaderNode::Uniform::HINT_BLACK_ALBEDO; } 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; } uniform2.hint = ShaderNode::Uniform::HINT_COLOR; @@ -9514,7 +9536,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ } break; 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); r_options->push_back(option); } else if ((completion_base == DataType::TYPE_INT || completion_base == DataType::TYPE_FLOAT) && !completion_base_array) { |