Blender V4.3
util/color.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#ifndef __UTIL_COLOR_H__
6#define __UTIL_COLOR_H__
7
8#include "util/math.h"
9#include "util/types.h"
10
11#if !defined(__KERNEL_GPU__) && defined(__KERNEL_SSE2__)
12# include "util/simd.h"
13#endif
14
16
18{
19 return ((val <= 0.0f) ? 0 :
20 ((val > (1.0f - 0.5f / 255.0f)) ? 255 : (uchar)((255.0f * val) + 0.5f)));
21}
22
24{
25 return val * (1.0f / 255.0f);
26}
27
29{
30 uchar r, g, b;
31
32 r = float_to_byte(c.x);
33 g = float_to_byte(c.y);
34 b = float_to_byte(c.z);
35
36 return make_uchar4(r, g, b, 0);
37}
38
40{
41 uchar r, g, b, a;
42
43 r = float_to_byte(c.x);
44 g = float_to_byte(c.y);
45 b = float_to_byte(c.z);
46 a = float_to_byte(c.w);
47
48 return make_uchar4(r, g, b, a);
49}
50
52{
53 return make_float3(c.x * (1.0f / 255.0f), c.y * (1.0f / 255.0f), c.z * (1.0f / 255.0f));
54}
55
57{
58 return make_float4(
59 c.x * (1.0f / 255.0f), c.y * (1.0f / 255.0f), c.z * (1.0f / 255.0f), c.w * (1.0f / 255.0f));
60}
61
63{
64 if (c < 0.04045f) {
65 return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
66 }
67 else {
68 return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
69 }
70}
71
73{
74 if (c < 0.0031308f) {
75 return (c < 0.0f) ? 0.0f : c * 12.92f;
76 }
77 else {
78 return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
79 }
80}
81
83{
84 float cmax, cmin, h, s, v, cdelta;
85 float3 c;
86
87 cmax = fmaxf(rgb.x, fmaxf(rgb.y, rgb.z));
88 cmin = min(rgb.x, min(rgb.y, rgb.z));
89 cdelta = cmax - cmin;
90
91 v = cmax;
92
93 if (cmax != 0.0f) {
94 s = cdelta / cmax;
95 }
96 else {
97 s = 0.0f;
98 h = 0.0f;
99 }
100
101 if (s != 0.0f) {
102 float3 cmax3 = make_float3(cmax, cmax, cmax);
103 c = (cmax3 - rgb) / cdelta;
104
105 if (rgb.x == cmax) {
106 h = c.z - c.y;
107 }
108 else if (rgb.y == cmax) {
109 h = 2.0f + c.x - c.z;
110 }
111 else {
112 h = 4.0f + c.y - c.x;
113 }
114
115 h /= 6.0f;
116
117 if (h < 0.0f) {
118 h += 1.0f;
119 }
120 }
121 else {
122 h = 0.0f;
123 }
124
125 return make_float3(h, s, v);
126}
127
129{
130 float i, f, p, q, t, h, s, v;
131 float3 rgb;
132
133 h = hsv.x;
134 s = hsv.y;
135 v = hsv.z;
136
137 if (s != 0.0f) {
138 if (h == 1.0f) {
139 h = 0.0f;
140 }
141
142 h *= 6.0f;
143 i = floorf(h);
144 f = h - i;
145 rgb = make_float3(f, f, f);
146 p = v * (1.0f - s);
147 q = v * (1.0f - (s * f));
148 t = v * (1.0f - (s * (1.0f - f)));
149
150 if (i == 0.0f) {
151 rgb = make_float3(v, t, p);
152 }
153 else if (i == 1.0f) {
154 rgb = make_float3(q, v, p);
155 }
156 else if (i == 2.0f) {
157 rgb = make_float3(p, v, t);
158 }
159 else if (i == 3.0f) {
160 rgb = make_float3(p, q, v);
161 }
162 else if (i == 4.0f) {
163 rgb = make_float3(t, p, v);
164 }
165 else {
166 rgb = make_float3(v, p, q);
167 }
168 }
169 else {
170 rgb = make_float3(v, v, v);
171 }
172
173 return rgb;
174}
175
177{
178 float cmax, cmin, h, s, l;
179
180 cmax = fmaxf(rgb.x, fmaxf(rgb.y, rgb.z));
181 cmin = min(rgb.x, min(rgb.y, rgb.z));
182 l = min(1.0f, (cmax + cmin) / 2.0f);
183
184 if (cmax == cmin) {
185 h = s = 0.0f; /* achromatic */
186 }
187 else {
188 float cdelta = cmax - cmin;
189 s = l > 0.5f ? cdelta / (2.0f - cmax - cmin) : cdelta / (cmax + cmin);
190 if (cmax == rgb.x) {
191 h = (rgb.y - rgb.z) / cdelta + (rgb.y < rgb.z ? 6.0f : 0.0f);
192 }
193 else if (cmax == rgb.y) {
194 h = (rgb.z - rgb.x) / cdelta + 2.0f;
195 }
196 else {
197 h = (rgb.x - rgb.y) / cdelta + 4.0f;
198 }
199 }
200 h /= 6.0f;
201
202 return make_float3(h, s, l);
203}
204
206{
207 float nr, ng, nb, chroma, h, s, l;
208
209 h = hsl.x;
210 s = hsl.y;
211 l = hsl.z;
212
213 nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
214 ng = 2.0f - fabsf(h * 6.0f - 2.0f);
215 nb = 2.0f - fabsf(h * 6.0f - 4.0f);
216
217 nr = clamp(nr, 0.0f, 1.0f);
218 nb = clamp(nb, 0.0f, 1.0f);
219 ng = clamp(ng, 0.0f, 1.0f);
220
221 chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s;
222
223 return make_float3((nr - 0.5f) * chroma + l, (ng - 0.5f) * chroma + l, (nb - 0.5f) * chroma + l);
224}
225
226ccl_device float3 xyY_to_xyz(float x, float y, float Y)
227{
228 float X, Z;
229
230 if (y != 0.0f) {
231 X = (x / y) * Y;
232 }
233 else {
234 X = 0.0f;
235 }
236
237 if (y != 0.0f && Y != 0.0f) {
238 Z = (1.0f - x - y) / y * Y;
239 }
240 else {
241 Z = 0.0f;
242 }
243
244 return make_float3(X, Y, Z);
245}
246
247#ifdef __KERNEL_SSE2__
248/*
249 * Calculate initial guess for arg^exp based on float representation
250 * This method gives a constant bias,
251 * which can be easily compensated by multiplication with bias_coeff.
252 * Gives better results for exponents near 1 (e. g. 4/5).
253 * exp = exponent, encoded as uint32_t
254 * e2coeff = 2^(127/exponent - 127) * bias_coeff^(1/exponent), encoded as uint32_t
255 */
256template<unsigned exp, unsigned e2coeff> ccl_device_inline float4 fastpow_sse2(const float4 &arg)
257{
258 float4 ret = arg * cast(make_int4(e2coeff));
260 ret = ret * cast(make_int4(exp));
261 ret = cast(make_int4(ret));
262 return ret;
263}
264
265/* Improve x ^ 1.0f/5.0f solution with Newton-Raphson method */
266ccl_device_inline float4 improve_5throot_solution_sse2(const float4 &old_result, const float4 &x)
267{
268 float4 approx2 = old_result * old_result;
269 float4 approx4 = approx2 * approx2;
270 float4 t = x / approx4;
271 float4 summ = madd(make_float4(4.0f), old_result, t);
272 return summ * make_float4(1.0f / 5.0f);
273}
274
275/* Calculate powf(x, 2.4). Working domain: 1e-10 < x < 1e+10 */
276ccl_device_inline float4 fastpow24_sse2(const float4 &arg)
277{
278 /* `max`, `avg` and |avg| errors were calculated in GCC without FMA instructions.
279 * The final precision should be better than `powf` in GLIBC. */
280
281 /* Calculate x^4/5, coefficient 0.994 was constructed manually to minimize avg error */
282 /* 0x3F4CCCCD = 4/5 */
283 /* 0x4F55A7FB = 2^(127/(4/5) - 127) * 0.994^(1/(4/5)) */
284 float4 x = fastpow_sse2<0x3F4CCCCD, 0x4F55A7FB>(
285 arg); // error max = 0.17 avg = 0.0018 |avg| = 0.05
286 float4 arg2 = arg * arg;
287 float4 arg4 = arg2 * arg2;
288
289 /* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */
290 x = improve_5throot_solution_sse2(x, arg4);
291 /* error max = 0.00021 avg = 1.6e-05 |avg| = 1.6e-05 */
292 x = improve_5throot_solution_sse2(x, arg4);
293 /* error max = 6.1e-07 avg = 5.2e-08 |avg| = 1.1e-07 */
294 x = improve_5throot_solution_sse2(x, arg4);
295
296 return x * (x * x);
297}
298
299ccl_device float4 color_srgb_to_linear_sse2(const float4 &c)
300{
301 int4 cmp = c < make_float4(0.04045f);
302 float4 lt = max(c * make_float4(1.0f / 12.92f), make_float4(0.0f));
303 float4 gtebase = (c + make_float4(0.055f)) * make_float4(1.0f / 1.055f); /* fma */
304 float4 gte = fastpow24_sse2(gtebase);
305 return select(cmp, lt, gte);
306}
307#endif /* __KERNEL_SSE2__ */
308
314
320
326
328{
329#ifdef __KERNEL_SSE2__
330 float4 r = c;
331 r = color_srgb_to_linear_sse2(r);
332 r.w = c.w;
333 return r;
334#else
335 return make_float4(
337#endif
338}
339
341{
342 color += one_float3();
343 if (variance) {
344 *variance *= sqr(one_float3() / color);
345 }
346 return log(color);
347}
348
353
355
356#endif /* __UTIL_COLOR_H__ */
unsigned char uchar
#define X
#define Z
#define Y
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert * v
local_group_size(16, 16) .push_constant(Type b
#define ccl_device
#define ccl_private
#define ccl_device_inline
#define powf(x, y)
#define CCL_NAMESPACE_END
ccl_device_forceinline float4 make_float4(const float x, const float y, const float z, const float w)
ccl_device_forceinline float3 make_float3(const float x, const float y, const float z)
ccl_device_forceinline uchar4 make_uchar4(const uchar x, const uchar y, const uchar z, const uchar w)
#define fmaxf(x, y)
#define floorf(x)
#define fabsf(x)
ccl_device_forceinline int4 make_int4(const int x, const int y, const int z, const int w)
CCL_NAMESPACE_BEGIN ccl_device_inline float madd(const float a, const float b, const float c)
Definition math_fast.h:29
ccl_device_inline float3 one_float3()
Definition math_float3.h:24
ccl_device_inline float3 exp(float3 v)
ccl_device_inline float3 log(float3 v)
ccl_device_inline int4 cast(const float4 a)
Definition math_float4.h:29
ccl_device_inline float4 select(const int4 mask, const float4 a, const float4 b)
return ret
#define min(a, b)
Definition sort.c:32
float z
Definition sky_float3.h:27
float y
Definition sky_float3.h:27
float x
Definition sky_float3.h:27
uchar z
uchar w
uchar x
uchar y
VecBase< float, 4 > float4
float max
ccl_device float3 hsl_to_rgb(float3 hsl)
Definition util/color.h:205
ccl_device float color_linear_to_srgb(float c)
Definition util/color.h:72
ccl_device float3 color_highlight_compress(float3 color, ccl_private float3 *variance)
Definition util/color.h:340
ccl_device float3 xyY_to_xyz(float x, float y, float Y)
Definition util/color.h:226
ccl_device_inline float4 color_uchar4_to_float4(uchar4 c)
Definition util/color.h:56
ccl_device uchar4 color_float4_to_uchar4(float4 c)
Definition util/color.h:39
ccl_device float3 color_srgb_to_linear_v3(float3 c)
Definition util/color.h:309
ccl_device float4 color_linear_to_srgb_v4(float4 c)
Definition util/color.h:321
ccl_device float3 rgb_to_hsv(float3 rgb)
Definition util/color.h:82
ccl_device float3 color_highlight_uncompress(float3 color)
Definition util/color.h:349
ccl_device float4 color_srgb_to_linear_v4(float4 c)
Definition util/color.h:327
ccl_device float3 color_linear_to_srgb_v3(float3 c)
Definition util/color.h:315
ccl_device float3 hsv_to_rgb(float3 hsv)
Definition util/color.h:128
ccl_device float color_srgb_to_linear(float c)
Definition util/color.h:62
ccl_device float byte_to_float(uchar val)
Definition util/color.h:23
ccl_device float3 rgb_to_hsl(float3 rgb)
Definition util/color.h:176
ccl_device_inline float3 color_byte_to_float(uchar4 c)
Definition util/color.h:51
ccl_device uchar4 color_float_to_byte(float3 c)
Definition util/color.h:28
CCL_NAMESPACE_BEGIN ccl_device uchar float_to_byte(float val)
Definition util/color.h:17
ccl_device_inline float sqr(float a)
Definition util/math.h:782
ccl_device_inline int clamp(int a, int mn, int mx)
Definition util/math.h:379