Skip to content

Commit

Permalink
Add srgb_color shader hint.
Browse files Browse the repository at this point in the history
Sometimes shaders want to accept a color as input that is always
in the srgb color space.  This adds a hint to vec3/vec4 to enable
the color picker popup for those vectors but disable color space
conversion.
  • Loading branch information
basicer committed Oct 4, 2024
1 parent 5ccbf6e commit 27c9ce9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 11 deletions.
3 changes: 3 additions & 0 deletions drivers/gles3/storage/material_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,9 @@ void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguag
if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_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);
} else if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SRGB_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);
} else {
//else just zero it out
_fill_std140_ubo_empty(E.value.type, E.value.array_size, data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,11 @@ void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringNa

if (V) {
//user provided
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->value, data, p_use_linear_color);
if (E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SRGB_COLOR) {
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->value, data, false);
} else {
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->value, data, p_use_linear_color);
}

} else if (E.value.default_value.size()) {
//default value
Expand All @@ -791,6 +795,8 @@ void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap<StringNa
if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_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 if ((E.value.type == ShaderLanguage::TYPE_VEC3 || E.value.type == ShaderLanguage::TYPE_VEC4) && E.value.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SRGB_COLOR) {
_fill_std140_variant_ubo_value(E.value.type, E.value.array_size, Color(0, 0, 0, 1), data, false);
} else {
//else just zero it out
_fill_std140_ubo_empty(E.value.type, E.value.array_size, data);
Expand Down
37 changes: 27 additions & 10 deletions servers/rendering/shader_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"HINT_ROUGHNESS_GRAY",
"HINT_ANISOTROPY_TEXTURE",
"HINT_SOURCE_COLOR",
"HINT_SRGB_COLOR",
"HINT_RANGE",
"HINT_ENUM",
"HINT_INSTANCE_INDEX",
Expand Down Expand Up @@ -367,6 +368,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
// hints

{ TK_HINT_SOURCE_COLOR, "source_color", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_SRGB_COLOR, "srgb_color", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_RANGE, "hint_range", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_ENUM, "hint_enum", CF_UNSPECIFIED, {}, {} },
{ TK_HINT_INSTANCE_INDEX, "instance_index", CF_UNSPECIFIED, {}, {} },
Expand Down Expand Up @@ -1187,6 +1189,9 @@ String ShaderLanguage::get_uniform_hint_name(ShaderNode::Uniform::Hint p_hint) {
case ShaderNode::Uniform::HINT_SOURCE_COLOR: {
result = "source_color";
} break;
case ShaderNode::Uniform::HINT_SRGB_COLOR: {
result = "srgb_color";
} break;
case ShaderNode::Uniform::HINT_NORMAL: {
result = "hint_normal";
} break;
Expand Down Expand Up @@ -4186,6 +4191,10 @@ bool ShaderLanguage::is_sampler_type(DataType p_type) {
return p_type > TYPE_MAT4 && p_type < TYPE_STRUCT;
}

bool ShaderLanguage::ShaderLanguage::is_hint_color(const ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
return p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR || p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SRGB_COLOR;
}

Variant ShaderLanguage::constant_value_to_variant(const Vector<Scalar> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
int array_size = p_array_size;

Expand Down Expand Up @@ -4370,7 +4379,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<Scalar> &p_value,
if (array_size > 0) {
array_size *= 3;

if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_hint)) {
PackedColorArray array;
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));
Expand All @@ -4384,7 +4393,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<Scalar> &p_value,
value = Variant(array);
}
} else {
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_hint)) {
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));
Expand All @@ -4395,7 +4404,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<Scalar> &p_value,
if (array_size > 0) {
array_size *= 4;

if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_hint)) {
PackedColorArray array;
for (int i = 0; i < array_size; i += 4) {
array.push_back(Color(p_value[i].real, p_value[i + 1].real, p_value[i + 2].real, p_value[i + 3].real));
Expand All @@ -4409,7 +4418,7 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<Scalar> &p_value,
value = Variant(array);
}
} else {
if (p_hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_hint)) {
value = Variant(Color(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
} else {
value = Variant(Vector4(p_value[0].real, p_value[1].real, p_value[2].real, p_value[3].real));
Expand Down Expand Up @@ -4622,14 +4631,14 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
break;
case ShaderLanguage::TYPE_VEC3:
if (p_uniform.array_size > 0) {
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
pi.type = Variant::PACKED_COLOR_ARRAY;
} else {
pi.type = Variant::PACKED_VECTOR3_ARRAY;
}
} else {
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
pi.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
pi.type = Variant::COLOR;
} else {
Expand All @@ -4639,13 +4648,13 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
break;
case ShaderLanguage::TYPE_VEC4: {
if (p_uniform.array_size > 0) {
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
pi.type = Variant::PACKED_COLOR_ARRAY;
} else {
pi.type = Variant::PACKED_VECTOR4_ARRAY;
}
} else {
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) {
if (ShaderLanguage::is_hint_color(p_uniform.hint)) {
pi.type = Variant::COLOR;
} else {
pi.type = Variant::VECTOR4;
Expand Down Expand Up @@ -9378,7 +9387,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f

if (uniform.array_size > 0) {
static Vector<int> supported_hints = {
TK_HINT_SOURCE_COLOR, TK_REPEAT_DISABLE, TK_REPEAT_ENABLE,
TK_HINT_SOURCE_COLOR, TK_HINT_SRGB_COLOR, TK_REPEAT_DISABLE, TK_REPEAT_ENABLE,
TK_FILTER_LINEAR, TK_FILTER_LINEAR_MIPMAP, TK_FILTER_LINEAR_MIPMAP_ANISOTROPIC,
TK_FILTER_NEAREST, TK_FILTER_NEAREST_MIPMAP, TK_FILTER_NEAREST_MIPMAP_ANISOTROPIC
};
Expand Down Expand Up @@ -9409,6 +9418,13 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
new_hint = ShaderNode::Uniform::HINT_SOURCE_COLOR;
}
} break;
case TK_HINT_SRGB_COLOR: {
if (type != TYPE_VEC3 && type != TYPE_VEC4) {
_set_error(vformat(RTR("Source color hint is for '%s', '%s'."), "vec3", "vec4"));
return ERR_PARSE_ERROR;
}
new_hint = ShaderNode::Uniform::HINT_SRGB_COLOR;
} break;
case TK_HINT_DEFAULT_BLACK_TEXTURE: {
new_hint = ShaderNode::Uniform::HINT_DEFAULT_BLACK;
} break;
Expand Down Expand Up @@ -9651,7 +9667,7 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f
break;
}

bool is_sampler_hint = new_hint != ShaderNode::Uniform::HINT_NONE && new_hint != ShaderNode::Uniform::HINT_SOURCE_COLOR && new_hint != ShaderNode::Uniform::HINT_RANGE && new_hint != ShaderNode::Uniform::HINT_ENUM;
bool is_sampler_hint = new_hint != ShaderNode::Uniform::HINT_NONE && new_hint != ShaderNode::Uniform::HINT_SOURCE_COLOR && new_hint != ShaderNode::Uniform::HINT_SRGB_COLOR && new_hint != ShaderNode::Uniform::HINT_RANGE && new_hint != ShaderNode::Uniform::HINT_ENUM;
if (((new_filter != FILTER_DEFAULT || new_repeat != REPEAT_DEFAULT) || is_sampler_hint) && !is_sampler_type(type)) {
_set_error(RTR("This hint is only for sampler types."));
return ERR_PARSE_ERROR;
Expand Down Expand Up @@ -11393,6 +11409,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_
if (completion_base_array) {
if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
options.push_back("source_color");
options.push_back("srgb_color");
}
} else {
if (current_uniform_hint == ShaderNode::Uniform::HINT_NONE) {
Expand Down
3 changes: 3 additions & 0 deletions servers/rendering/shader_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ class ShaderLanguage {
TK_HINT_ROUGHNESS_GRAY,
TK_HINT_ANISOTROPY_TEXTURE,
TK_HINT_SOURCE_COLOR,
TK_HINT_SRGB_COLOR,
TK_HINT_RANGE,
TK_HINT_ENUM,
TK_HINT_INSTANCE_INDEX,
Expand Down Expand Up @@ -639,6 +640,7 @@ class ShaderLanguage {
HINT_RANGE,
HINT_ENUM,
HINT_SOURCE_COLOR,
HINT_SRGB_COLOR,
HINT_NORMAL,
HINT_ROUGHNESS_NORMAL,
HINT_ROUGHNESS_R,
Expand Down Expand Up @@ -821,6 +823,7 @@ class ShaderLanguage {
static bool is_scalar_type(DataType p_type);
static bool is_float_type(DataType p_type);
static bool is_sampler_type(DataType p_type);
static bool is_hint_color(const ShaderNode::Uniform::Hint p_hint);
static Variant constant_value_to_variant(const Vector<Scalar> &p_value, DataType p_type, int p_array_size, ShaderLanguage::ShaderNode::Uniform::Hint p_hint = ShaderLanguage::ShaderNode::Uniform::HINT_NONE);
static PropertyInfo uniform_to_property_info(const ShaderNode::Uniform &p_uniform);
static uint32_t get_datatype_size(DataType p_type);
Expand Down

0 comments on commit 27c9ce9

Please sign in to comment.