ai_color.h
Go to the documentation of this file.
1// Copyright 2021 Autodesk, Inc. All rights reserved.
2//
3// Use of this software is subject to the terms of the Autodesk license
4// agreement provided at the time of installation or download, or which
5// otherwise accompanies this software in either electronic or hard copy form.
6
12#pragma once
13#include "ai_comparison.h"
14#include "ai_math.h"
15#include "ai_string.h"
16#include "ai_constants.h"
17#include "ai_api.h"
18
19struct AtRGBA;
20
31struct AtRGB
32{
33 float r, g, b;
34
35 AtRGB() = default;
36 AI_DEVICE constexpr explicit AtRGB(float c) : r(c), g(c), b(c) { }
37 AI_DEVICE constexpr AtRGB(float r, float g, float b) : r(r), g(g), b(b) { }
38 AI_DEVICE constexpr explicit AtRGB(const AtRGBA& rgba);
39
40 AI_DEVICE constexpr AtRGB operator+(const AtRGB& rgb) const
41 {
42 return AtRGB(r + rgb.r,
43 g + rgb.g,
44 b + rgb.b);
45 }
46
47 AI_DEVICE AtRGB& operator+=(const AtRGB& rgb)
48 {
49 r += rgb.r;
50 g += rgb.g;
51 b += rgb.b;
52 return *this;
53 }
54
55 AI_DEVICE constexpr AtRGB operator+(float f) const
56 {
57 return AtRGB(r + f,
58 g + f,
59 b + f);
60 }
61
62 AI_DEVICE AtRGB& operator+=(float f)
63 {
64 r += f;
65 g += f;
66 b += f;
67 return *this;
68 }
69
70 AI_DEVICE constexpr AtRGB operator-(const AtRGB& rgb) const
71 {
72 return AtRGB(r - rgb.r,
73 g - rgb.g,
74 b - rgb.b);
75 }
76
77 AI_DEVICE AtRGB& operator-=(const AtRGB& rgb)
78 {
79 r -= rgb.r;
80 g -= rgb.g;
81 b -= rgb.b;
82 return *this;
83 }
84
85 AI_DEVICE constexpr AtRGB operator-(float f) const
86 {
87 return AtRGB(r - f,
88 g - f,
89 b - f);
90 }
91
92 AI_DEVICE AtRGB& operator-=(float f)
93 {
94 r -= f;
95 g -= f;
96 b -= f;
97 return *this;
98 }
99
100 AI_DEVICE constexpr AtRGB operator-() const
101 {
102 return AtRGB(-r, -g, -b);
103 }
104
105 AI_DEVICE constexpr AtRGB operator*(const AtRGB& rgb) const
106 {
107 return AtRGB(r * rgb.r,
108 g * rgb.g,
109 b * rgb.b);
110 }
111
112 AI_DEVICE AtRGB operator*=(const AtRGB& rgb)
113 {
114 r *= rgb.r;
115 g *= rgb.g;
116 b *= rgb.b;
117 return *this;
118 }
119
120 AI_DEVICE constexpr AtRGB operator*(float f) const
121 {
122 return AtRGB(r * f,
123 g * f,
124 b * f);
125 }
126
127 AI_DEVICE AtRGB operator*=(float f)
128 {
129 r *= f;
130 g *= f;
131 b *= f;
132 return *this;
133 }
134
135 AI_DEVICE constexpr AtRGB operator/(const AtRGB& rgb) const
136 {
137 return AtRGB(r / rgb.r,
138 g / rgb.g,
139 b / rgb.b);
140 }
141
142 AI_DEVICE AtRGB operator/=(const AtRGB& rgb)
143 {
144 r /= rgb.r;
145 g /= rgb.g;
146 b /= rgb.b;
147 return *this;
148 }
149
150 AI_DEVICE AtRGB operator/(float f) const
151 {
152 return AtRGB(r / f,
153 g / f,
154 b / f);
155 }
156
157 AI_DEVICE AtRGB operator/=(float f)
158 {
159 r /= f;
160 g /= f;
161 b /= f;
162 return *this;
163 }
164
165 AI_DEVICE constexpr bool operator==(const AtRGB& rgb) const
166 {
167 return (r == rgb.r && g == rgb.g && b == rgb.b);
168 }
169
170 AI_DEVICE constexpr bool operator!=(const AtRGB& rgb) const
171 {
172 return !(*this == rgb);
173 }
174
175 AI_DEVICE AtRGB& operator=(float f)
176 {
177 r = f;
178 g = f;
179 b = f;
180 return *this;
181 }
182
183 AI_DEVICE float& operator[](unsigned int i)
184 {
185 return *(&r + i); // warning: no bounds checking!
186 }
187
188 AI_DEVICE constexpr const float& operator[](unsigned int i) const
189 {
190 return *(&r + i); // warning: no bounds checking!
191 }
192
193 AI_DEVICE friend constexpr AtRGB operator*(float f, const AtRGB& rgb);
194 AI_DEVICE friend constexpr AtRGB operator+(float f, const AtRGB& rgb);
195 AI_DEVICE friend constexpr AtRGB operator-(float f, const AtRGB& rgb);
196};
197
198AI_DEVICE inline constexpr AtRGB operator*(float f, const AtRGB& rgb)
199{
200 return rgb * f;
201}
202
203AI_DEVICE inline constexpr AtRGB operator+(float f, const AtRGB& rgb)
204{
205 return rgb + f;
206}
207
208AI_DEVICE inline constexpr AtRGB operator-(float f, const AtRGB& rgb)
209{
210 return AtRGB(f - rgb.r,
211 f - rgb.g,
212 f - rgb.b);
213}
214
215AI_DEVICE inline constexpr AtRGB operator/(float f, const AtRGB& rgb)
216{
217 return AtRGB(f / rgb.r,
218 f / rgb.g,
219 f / rgb.b);
220}
221
222AI_DEVICE inline AtBooleanMask<3> operator<(const AtRGB& lhs, const AtRGB& rhs)
223{
224 return AtBooleanMask<3>::lt(&(lhs[0]), &(rhs[0]));
225}
226
227AI_DEVICE inline AtBooleanMask<3> operator<=(const AtRGB& lhs, const AtRGB& rhs)
228{
229 return AtBooleanMask<3>::le(&(lhs[0]), &(rhs[0]));
230}
231
232AI_DEVICE inline AtBooleanMask<3> operator>(const AtRGB& lhs, const AtRGB& rhs)
233{
234 return AtBooleanMask<3>::gt(&(lhs[0]), &(rhs[0]));
235}
236
237AI_DEVICE inline AtBooleanMask<3> operator>=(const AtRGB& lhs, const AtRGB& rhs)
238{
239 return AtBooleanMask<3>::ge(&(lhs[0]), &(rhs[0]));
240}
241
242AI_DEVICE inline AtBooleanMask<3> operator<(const AtRGB& lhs, float rhs)
243{
244 return AtBooleanMask<3>::lt(&(lhs[0]), rhs);
245}
246
247AI_DEVICE inline AtBooleanMask<3> operator<=(const AtRGB& lhs, float rhs)
248{
249 return AtBooleanMask<3>::le(&(lhs[0]), rhs);
250}
251
252AI_DEVICE inline AtBooleanMask<3> operator>(const AtRGB& lhs, float rhs)
253{
254 return AtBooleanMask<3>::gt(&(lhs[0]), rhs);
255}
256
257AI_DEVICE inline AtBooleanMask<3> operator>=(const AtRGB& lhs, float rhs)
258{
259 return AtBooleanMask<3>::ge(&(lhs[0]), rhs);
260}
261
262
266struct AtRGBA
267{
268 float r, g, b, a;
269
270 AtRGBA() = default;
271 AI_DEVICE constexpr AtRGBA(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) { }
272 AI_DEVICE constexpr AtRGBA(const AtRGB& rgb, float a=1) : r(rgb.r), g(rgb.g), b(rgb.b), a(a) { }
273
274 AI_DEVICE AtRGB& rgb()
275 {
276 return *static_cast<AtRGB*>(static_cast<void*>(this));
277 }
278
279 AI_DEVICE const AtRGB& rgb() const
280 {
281 return *static_cast<const AtRGB*>(static_cast<const void*>(this));
282 }
283
284 AI_DEVICE constexpr AtRGBA operator+(const AtRGBA& rgba) const
285 {
286 return AtRGBA(r + rgba.r,
287 g + rgba.g,
288 b + rgba.b,
289 a + rgba.a);
290 }
291
292 AI_DEVICE AtRGBA& operator+=(const AtRGBA& rgba)
293 {
294 r += rgba.r;
295 g += rgba.g;
296 b += rgba.b;
297 a += rgba.a;
298 return *this;
299 }
300
301 AI_DEVICE constexpr AtRGBA operator+(float f) const
302 {
303 return AtRGBA(r + f,
304 g + f,
305 b + f,
306 a + f);
307 }
308
309 AI_DEVICE AtRGBA& operator+=(float f)
310 {
311 r += f;
312 g += f;
313 b += f;
314 a += f;
315 return *this;
316 }
317
318 AI_DEVICE constexpr AtRGBA operator-(const AtRGBA& rgba) const
319 {
320 return AtRGBA(r - rgba.r,
321 g - rgba.g,
322 b - rgba.b,
323 a - rgba.a);
324 }
325
326 AI_DEVICE AtRGBA& operator-=(const AtRGBA& rgba)
327 {
328 r -= rgba.r;
329 g -= rgba.g;
330 b -= rgba.b;
331 a -= rgba.a;
332 return *this;
333 }
334
335 AI_DEVICE constexpr AtRGBA operator-(float f) const
336 {
337 return AtRGBA(r - f,
338 g - f,
339 b - f,
340 a - f);
341 }
342
343 AI_DEVICE AtRGBA& operator-=(float f)
344 {
345 r -= f;
346 g -= f;
347 b -= f;
348 a -= f;
349 return *this;
350 }
351
352 AI_DEVICE constexpr AtRGBA operator-() const
353 {
354 return AtRGBA(-r, -g, -b, -a);
355 }
356
357 AI_DEVICE constexpr AtRGBA operator*(const AtRGBA& rgba) const
358 {
359 return AtRGBA(r * rgba.r,
360 g * rgba.g,
361 b * rgba.b,
362 a * rgba.a);
363 }
364
365 AI_DEVICE AtRGBA operator*=(const AtRGBA& rgba)
366 {
367 r *= rgba.r;
368 g *= rgba.g;
369 b *= rgba.b;
370 a *= rgba.a;
371 return *this;
372 }
373
374 AI_DEVICE constexpr AtRGBA operator*(float f) const
375 {
376 return AtRGBA(r * f,
377 g * f,
378 b * f,
379 a * f);
380 }
381
382 AI_DEVICE AtRGBA operator*=(float f)
383 {
384 r *= f;
385 g *= f;
386 b *= f;
387 a *= f;
388 return *this;
389 }
390
391 AI_DEVICE constexpr AtRGBA operator/(const AtRGBA& rgba) const
392 {
393 return AtRGBA(r / rgba.r,
394 g / rgba.g,
395 b / rgba.b,
396 a / rgba.a);
397 }
398
399 AI_DEVICE AtRGBA operator/=(const AtRGBA& rgba)
400 {
401 r /= rgba.r;
402 g /= rgba.g;
403 b /= rgba.b;
404 a /= rgba.a;
405 return *this;
406 }
407
408 AI_DEVICE AtRGBA operator/(float f) const
409 {
410 return AtRGBA(r / f,
411 g / f,
412 b / f,
413 a / f);
414 }
415
416 AI_DEVICE AtRGBA operator/=(float f)
417 {
418 r /= f;
419 g /= f;
420 b /= f;
421 a /= f;
422 return *this;
423 }
424
425 AI_DEVICE constexpr bool operator==(const AtRGBA& rgba) const
426 {
427 return (r == rgba.r && g == rgba.g && b == rgba.b && a == rgba.a);
428 }
429
430 AI_DEVICE constexpr bool operator!=(const AtRGBA& rgba) const
431 {
432 return !(*this == rgba);
433 }
434
435 AI_DEVICE AtRGBA& operator=(float f)
436 {
437 r = f;
438 g = f;
439 b = f;
440 a = f;
441 return *this;
442 }
443
444 AI_DEVICE float& operator[](unsigned int i)
445 {
446 return *(&r + i); // warning: no bounds checking!
447 }
448
449 AI_DEVICE constexpr const float& operator[](unsigned int i) const
450 {
451 return *(&r + i); // warning: no bounds checking!
452 }
453
454 AI_DEVICE friend constexpr AtRGBA operator*(float f, const AtRGBA& rgba);
455 AI_DEVICE friend constexpr AtRGBA operator+(float f, const AtRGBA& rgba);
456 AI_DEVICE friend constexpr AtRGBA operator-(float f, const AtRGBA& rgba);
457};
458
459AI_DEVICE inline constexpr AtRGBA operator*(float f, const AtRGBA& rgba)
460{
461 return rgba * f;
462}
463
464AI_DEVICE inline constexpr AtRGBA operator+(float f, const AtRGBA& rgba)
465{
466 return rgba + f;
467}
468
469AI_DEVICE inline constexpr AtRGBA operator-(float f, const AtRGBA& rgba)
470{
471 return AtRGBA(f - rgba.r,
472 f - rgba.g,
473 f - rgba.b,
474 f - rgba.a);
475}
476
477inline AtBooleanMask<4> operator<(const AtRGBA& lhs, const AtRGBA& rhs)
478{
479 return AtBooleanMask<4>::lt(&(lhs[0]), &(rhs[0]));
480}
481
482inline AtBooleanMask<4> operator<=(const AtRGBA& lhs, const AtRGBA& rhs)
483{
484 return AtBooleanMask<4>::le(&(lhs[0]), &(rhs[0]));
485}
486
487inline AtBooleanMask<4> operator>(const AtRGBA& lhs, const AtRGBA& rhs)
488{
489 return AtBooleanMask<4>::gt(&(lhs[0]), &(rhs[0]));
490}
491
492inline AtBooleanMask<4> operator>=(const AtRGBA& lhs, const AtRGBA& rhs)
493{
494 return AtBooleanMask<4>::ge(&(lhs[0]), &(rhs[0]));
495}
496
497inline AtBooleanMask<4> operator<(const AtRGBA& lhs, float rhs)
498{
499 return AtBooleanMask<4>::lt(&(lhs[0]), rhs);
500}
501
502inline AtBooleanMask<4> operator<=(const AtRGBA& lhs, float rhs)
503{
504 return AtBooleanMask<4>::le(&(lhs[0]), rhs);
505}
506
507inline AtBooleanMask<4> operator>(const AtRGBA& lhs, float rhs)
508{
509 return AtBooleanMask<4>::gt(&(lhs[0]), rhs);
510}
511
512inline AtBooleanMask<4> operator>=(const AtRGBA& lhs, float rhs)
513{
514 return AtBooleanMask<4>::ge(&(lhs[0]), rhs);
515}
516
517AI_DEVICE inline constexpr AtRGB::AtRGB(const AtRGBA& rgba) : r(rgba.r), g(rgba.g), b(rgba.b) { }
518
519
527AI_DEVICE inline constexpr AtRGB AiRGBClamp(const AtRGB& c, float lo, float hi)
528{
529 return AtRGB(AiClamp(c.r, lo, hi),
530 AiClamp(c.g, lo, hi),
531 AiClamp(c.b, lo, hi));
532}
533
537AI_DEVICE inline constexpr AtRGBA AiRGBAClamp(const AtRGBA& c, float lo, float hi)
538{
539 return AtRGBA(AiClamp(c.r, lo, hi),
540 AiClamp(c.g, lo, hi),
541 AiClamp(c.b, lo, hi),
542 AiClamp(c.a, lo, hi));
543}
544
548AI_DEVICE inline void AiColorClipToZero(AtRGB& c)
549{
550 c.r = AiMax(c.r, 0.0f);
551 c.g = AiMax(c.g, 0.0f);
552 c.b = AiMax(c.b, 0.0f);
553}
554
558AI_DEVICE inline bool AiColorIsSmall(const AtRGB& c, float epsilon = AI_EPSILON)
559{
560 return std::abs(c.r) < epsilon && std::abs(c.g) < epsilon && std::abs(c.b) < epsilon;
561}
562
566AI_DEVICE inline AtRGB AiColorABS(const AtRGB& c)
567{
568 return AtRGB(std::abs(c.r),
569 std::abs(c.g),
570 std::abs(c.b));
571}
572
576AI_DEVICE inline AtRGBA AiColorABS(const AtRGBA& c)
577{
578 return AtRGBA(std::abs(c.r),
579 std::abs(c.g),
580 std::abs(c.b),
581 std::abs(c.a));
582}
583
587AI_DEVICE inline constexpr float AiColorMaxRGB(const AtRGB& c)
588{
589 return AiMax(c.r, c.g, c.b);
590}
591
595AI_DEVICE inline constexpr float AiColorMaxRGB(const AtRGBA& c)
596{
597 return AiMax(c.r, c.g, c.b);
598}
599
603inline bool AiColorThreshold(const AtRGB& c1, const AtRGB& c2, float t)
604{
605 return std::abs(c1.r - c2.r) >= t || std::abs(c1.g - c2.g) >= t || std::abs(c1.b - c2.b) >= t;
606}
607
611AI_DEVICE inline constexpr float AiColorToGrey(const AtRGB& c)
612{
613 return (c.r + c.g + c.b) / 3;
614}
615
619AI_DEVICE inline constexpr float AiColorToGrey(const AtRGBA& rgba)
620{
621 return (rgba.r + rgba.g + rgba.b) / 3;
622}
623
627AI_API AI_PURE bool AiRGBIsFinite(const AtRGB& rgba);
628
632AI_API AI_PURE bool AiRGBAIsFinite(const AtRGBA& rgba);
633
637inline AtRGB AiBerpRGB(float a, float b, const AtRGB& c0, const AtRGB& c1, const AtRGB& c2)
638{
639 float c = 1 - (a+b);
640 return c*c0 + a*c1 + b*c2;
641}
642
643AI_API AI_DEVICE AI_PURE AtRGB AiColorHeatMap(const AtRGB* map_colors, const float* map_values, unsigned int map_length, float lookup);
644
645/*\}*/
646
650#ifdef AI_CPU_COMPILER
651static constexpr const AtRGB AI_RGB_BLACK (0.0f, 0.0f, 0.0f);
652static constexpr const AtRGB AI_RGB_ZERO (0.0f, 0.0f, 0.0f);
653static constexpr const AtRGB AI_RGB_RED (1.0f, 0.0f, 0.0f);
654static constexpr const AtRGB AI_RGB_GREEN (0.0f, 1.0f, 0.0f);
655static constexpr const AtRGB AI_RGB_BLUE (0.0f, 0.0f, 1.0f);
656static constexpr const AtRGB AI_RGB_50GREY(0.5f, 0.5f, 0.5f);
657static constexpr const AtRGB AI_RGB_WHITE (1.0f, 1.0f, 1.0f);
658#else
659__device__ static const AtRGB AI_RGB_BLACK (0.0f, 0.0f, 0.0f);
660__device__ static const AtRGB AI_RGB_ZERO (0.0f, 0.0f, 0.0f);
661__device__ static const AtRGB AI_RGB_RED (1.0f, 0.0f, 0.0f);
662__device__ static const AtRGB AI_RGB_GREEN (0.0f, 1.0f, 0.0f);
663__device__ static const AtRGB AI_RGB_BLUE (0.0f, 0.0f, 1.0f);
664__device__ static const AtRGB AI_RGB_50GREY(0.5f, 0.5f, 0.5f);
665__device__ static const AtRGB AI_RGB_WHITE (1.0f, 1.0f, 1.0f);
666#endif
667
668#ifdef AI_CPU_COMPILER
669static constexpr const AtRGBA AI_RGBA_ZERO (0.0f, 0.0f, 0.0f, 0.0f);
670static constexpr const AtRGBA AI_RGBA_RED (1.0f, 0.0f, 0.0f, 1.0f);
671static constexpr const AtRGBA AI_RGBA_GREEN (0.0f, 1.0f, 0.0f, 1.0f);
672static constexpr const AtRGBA AI_RGBA_BLUE (0.0f, 0.0f, 1.0f, 1.0f);
673static constexpr const AtRGBA AI_RGBA_50GREY(0.5f, 0.5f, 0.5f, 1.0f);
674static constexpr const AtRGBA AI_RGBA_WHITE (1.0f, 1.0f, 1.0f, 1.0f);
675#else
676__device__ static const AtRGBA AI_RGBA_ZERO (0.0f, 0.0f, 0.0f, 0.0f);
677__device__ static const AtRGBA AI_RGBA_RED (1.0f, 0.0f, 0.0f, 1.0f);
678__device__ static const AtRGBA AI_RGBA_GREEN (0.0f, 1.0f, 0.0f, 1.0f);
679__device__ static const AtRGBA AI_RGBA_BLUE (0.0f, 0.0f, 1.0f, 1.0f);
680__device__ static const AtRGBA AI_RGBA_50GREY(0.5f, 0.5f, 0.5f, 1.0f);
681__device__ static const AtRGBA AI_RGBA_WHITE (1.0f, 1.0f, 1.0f, 1.0f);
682#endif
683
684/*\}*/
685
686/*\}*/
DLL export prefix for API functions (necessary for multi-platform development)
Comparison.
Various useful constants.
Math operations.
AtString class for fast comparisons.
AI_DEVICE AtRGB AiColorABS(const AtRGB &c)
Absolute value of color.
Definition: ai_color.h:566
AI_DEVICE void AiColorClipToZero(AtRGB &c)
Clip negative values.
Definition: ai_color.h:548
AI_API AI_PURE bool AiRGBAIsFinite(const AtRGBA &rgba)
Check to see if an RGBA color has any corrupted components (nan or infinite).
Definition: ai_color.cpp:63
bool AiColorThreshold(const AtRGB &c1, const AtRGB &c2, float t)
Check to see if two colors differ by more than a threhsold.
Definition: ai_color.h:603
AtRGB AiBerpRGB(float a, float b, const AtRGB &c0, const AtRGB &c1, const AtRGB &c2)
Barycentric interpolation of triangle vertex colors.
Definition: ai_color.h:637
AI_DEVICE constexpr float AiColorToGrey(const AtRGB &c)
Convert a RGB color to grey scale (take average of R, G, B)
Definition: ai_color.h:611
AI_DEVICE constexpr AtRGB AiRGBClamp(const AtRGB &c, float lo, float hi)
Clamp the RGB color vector to the specified range.
Definition: ai_color.h:527
AI_DEVICE constexpr float AiColorMaxRGB(const AtRGB &c)
Max RGB component of color.
Definition: ai_color.h:587
AI_API AI_PURE bool AiRGBIsFinite(const AtRGB &rgba)
Check to see if an RGB color has any corrupted components (nan or infinite).
Definition: ai_color.cpp:55
AI_DEVICE constexpr AtRGBA AiRGBAClamp(const AtRGBA &c, float lo, float hi)
Clamp the RGBA color vector to the specified range.
Definition: ai_color.h:537
AI_DEVICE bool AiColorIsSmall(const AtRGB &c, float epsilon=AI_EPSILON)
Check for almost black.
Definition: ai_color.h:558
AI_API AI_DEVICE AI_PURE AtRGB AiColorHeatMap(const AtRGB *map_colors, const float *map_values, unsigned int map_length, float lookup)
Interpolate a value according to a heat map (piecewise linear color map).
Definition: ai_color.cpp:19
#define AI_EPSILON
System epsilon value
Definition: ai_constants.h:41
AI_DEVICE constexpr T AiClamp(T v, T lo, T hi)
Clamp the input to the specified range.
Definition: ai_math.h:101
AI_DEVICE constexpr T AiMax(T a, T b)
Maximum of 'a' and 'b'.
Definition: ai_math.h:43
Definition: ai_comparison.h:17
RGB color + alpha.
Definition: ai_color.h:267
RGB color.
Definition: ai_color.h:32

© 2022 Autodesk, Inc. · All rights reserved · www.arnoldrenderer.com