Color Management: Change byte color attributes to always be sRGB

These don't really work as scene linear with sRGB transfer function for e.g.
ACEScg, there are not enough bits. If you want wide gamut you need to use
float colors.

Pull Request: https://projects.blender.org/blender/blender/pulls/145763
This commit is contained in:
Brecht Van Lommel
2025-09-02 11:37:56 +02:00
parent ffa4f8c7ad
commit 9856615813
5 changed files with 47 additions and 15 deletions

View File

@@ -6,6 +6,7 @@
#include "kernel/globals.h"
#include "kernel/types.h"
#include "kernel/util/colorspace.h"
#include "util/color.h"
@@ -123,8 +124,9 @@ ccl_device_inline T attribute_data_fetch_bytecolor(KernelGlobals /*kg*/, int /*o
ccl_device_template_spec float4 attribute_data_fetch_bytecolor(KernelGlobals kg, int offset)
{
return color_srgb_to_linear_v4(
const float4 rec709 = color_srgb_to_linear_v4(
color_uchar4_to_float4(kernel_data_fetch(attributes_uchar4, offset)));
return make_float4(rec709_to_rgb(kg, make_float3(rec709)), rec709.w);
}
ccl_device_template_spec Transform attribute_data_fetch(KernelGlobals kg, int offset)

View File

@@ -11,8 +11,10 @@
#include <ostream>
#include "BLI_color_types.hh"
#include "BLI_colorspace.hh"
#include "BLI_compiler_compat.h"
#include "BLI_math_color.h"
#include "BLI_math_vector.h"
namespace blender {
@@ -47,8 +49,12 @@ BLI_INLINE ColorTheme4b to_byte(const ColorTheme4b &theme4b)
template<eAlpha Alpha>
BLI_INLINE ColorSceneLinearByteEncoded4b<Alpha> encode(const ColorSceneLinear4f<Alpha> &color)
{
float4 value = static_cast<const float *>(color);
if (!colorspace::scene_linear_is_rec709) {
copy_v3_v3(value, colorspace::scene_linear_to_rec709 * value.xyz());
}
ColorSceneLinearByteEncoded4b<Alpha> encoded;
linearrgb_to_srgb_uchar4(encoded, color);
linearrgb_to_srgb_uchar4(encoded, value);
return encoded;
}
@@ -72,6 +78,9 @@ BLI_INLINE ColorSceneLinear4f<Alpha> decode(const ColorSceneLinearByteEncoded4b<
{
ColorSceneLinear4f<Alpha> decoded;
srgb_to_linearrgb_uchar4(decoded, color);
if (!blender::colorspace::scene_linear_is_rec709) {
copy_v3_v3(decoded, blender::colorspace::rec709_to_scene_linear * blender::float3(decoded));
}
return decoded;
}

View File

@@ -15,6 +15,8 @@
#include "GPU_vertex_format.hh"
#include "IMB_colormanagement.hh"
namespace blender::gpu {
class VertBuf;
}
@@ -117,9 +119,13 @@ template<> struct AttributeConverter<ColorGeometry4b> {
static constexpr GPUVertFetchMode gpu_fetch_mode = GPU_FETCH_INT_TO_FLOAT_UNIT;
static VBOType convert(const ColorGeometry4b &value)
{
return {unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.r]),
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.g]),
unit_float_to_ushort_clamp(BLI_color_from_srgb_table[value.b]),
blender::float3 rgb = {BLI_color_from_srgb_table[value.r],
BLI_color_from_srgb_table[value.g],
BLI_color_from_srgb_table[value.b]};
IMB_colormanagement_rec709_to_scene_linear(rgb, rgb);
return {unit_float_to_ushort_clamp(rgb[0]),
unit_float_to_ushort_clamp(rgb[1]),
unit_float_to_ushort_clamp(rgb[2]),
ushort(value.a * 257)};
}
};

View File

@@ -43,6 +43,8 @@
#include "DEG_depsgraph_query.hh"
#include "IMB_colormanagement.hh"
#include "draw_attributes.hh"
#include "draw_cache_impl.hh" /* own include */
#include "draw_hair_private.hh"
@@ -354,9 +356,13 @@ static void ensure_seg_pt_count(PTCacheEdit *edit,
static void particle_pack_mcol(MCol *mcol, ushort r_scol[3])
{
/* Convert to linear ushort and swizzle */
r_scol[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->b]);
r_scol[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->g]);
r_scol[2] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mcol->r]);
float3 col = {BLI_color_from_srgb_table[mcol->r],
BLI_color_from_srgb_table[mcol->g],
BLI_color_from_srgb_table[mcol->b]};
IMB_colormanagement_rec709_to_scene_linear(col, col);
r_scol[0] = unit_float_to_ushort_clamp(col[2]);
r_scol[1] = unit_float_to_ushort_clamp(col[1]);
r_scol[2] = unit_float_to_ushort_clamp(col[0]);
}
/* Used by parent particles and simple children. */
@@ -1309,12 +1315,13 @@ static int particle_mface_index(const ChildParticle &particle, int /*face_count_
static float4 particle_mcol_convert(const MCol &mcol)
{
float4 col;
/* Convert to linear ushort and swizzle */
col[0] = BLI_color_from_srgb_table[mcol.b];
col[1] = BLI_color_from_srgb_table[mcol.g];
col[2] = BLI_color_from_srgb_table[mcol.r];
col[3] = mcol.a / 255.0f;
float4 col = {BLI_color_from_srgb_table[mcol.r],
BLI_color_from_srgb_table[mcol.g],
BLI_color_from_srgb_table[mcol.b],
mcol.a / 255.0f};
IMB_colormanagement_rec709_to_scene_linear(col, col);
std::swap(col[0], col[2]);
return col;
}

View File

@@ -203,6 +203,8 @@ const EnumPropertyItem rna_enum_attribute_curves_domain_items[] = {
# include "BLT_translation.hh"
# include "IMB_colormanagement.hh"
# include "WM_api.hh"
using blender::StringRef;
@@ -577,11 +579,15 @@ static void rna_ByteColorAttributeValue_color_get(PointerRNA *ptr, float *values
{
MLoopCol *mlcol = (MLoopCol *)ptr->data;
srgb_to_linearrgb_uchar4(values, &mlcol->r);
IMB_colormanagement_rec709_to_scene_linear(values, values);
}
static void rna_ByteColorAttributeValue_color_set(PointerRNA *ptr, const float *values)
{
MLoopCol *mlcol = (MLoopCol *)ptr->data;
float rec709[4];
IMB_colormanagement_scene_linear_to_rec709(rec709, values);
rec709[3] = values[3];
linearrgb_to_srgb_uchar4(&mlcol->r, values);
}
@@ -606,13 +612,15 @@ static void rna_ByteColorAttributeValue_color_srgb_set(PointerRNA *ptr, const fl
static void rna_FloatColorAttributeValue_color_srgb_get(PointerRNA *ptr, float *values)
{
MPropCol *col = (MPropCol *)ptr->data;
linearrgb_to_srgb_v4(values, col->color);
IMB_colormanagement_scene_linear_to_srgb_v3(values, col->color);
values[3] = col->color[3];
}
static void rna_FloatColorAttributeValue_color_srgb_set(PointerRNA *ptr, const float *values)
{
MPropCol *col = (MPropCol *)ptr->data;
srgb_to_linearrgb_v4(col->color, values);
IMB_colormanagement_srgb_to_scene_linear_v3(col->color, values);
col->color[3] = values[3];
}
/* String Attribute */