mirror of
https://github.com/wled/WLED.git
synced 2025-07-19 08:46:34 +00:00
color_add() that preserves color ratio
AA version of setPixelColor(float) Fix in AA ratio calculation.
This commit is contained in:
parent
1e2cae7087
commit
4cc2dea2fe
@ -709,12 +709,15 @@ class WS2812FX {
|
|||||||
makeAutoSegments(bool forceReset = false),
|
makeAutoSegments(bool forceReset = false),
|
||||||
fixInvalidSegments(),
|
fixInvalidSegments(),
|
||||||
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
|
||||||
|
setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = false),
|
||||||
show(void),
|
show(void),
|
||||||
setTargetFps(uint8_t fps),
|
setTargetFps(uint8_t fps),
|
||||||
deserializeMap(uint8_t n=0);
|
deserializeMap(uint8_t n=0);
|
||||||
|
|
||||||
inline void setPixelColor(uint16_t n, uint32_t c) {setPixelColor(n, byte(c>>16), byte(c>>8), byte(c), byte(c>>24));}
|
inline void setPixelColor(uint16_t n, uint32_t c) {setPixelColor(n, byte(c>>16), byte(c>>8), byte(c), byte(c>>24));}
|
||||||
inline void setPixelColor(uint16_t n, CRGB &c) {setPixelColor(n, c.red, c.green, c.blue);}
|
inline void setPixelColor(uint16_t n, CRGB c) {setPixelColor(n, c.red, c.green, c.blue);}
|
||||||
|
inline void setPixelColor(float i, uint32_t c, bool aa = false) {setPixelColor(i, byte(c>>16), byte(c>>8), byte(c), byte(c>>24), aa);}
|
||||||
|
inline void setPixelColor(float i, CRGB c, bool aa = false) {setPixelColor(i, c.red, c.green, c.blue, 0, aa);}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
gammaCorrectBri = false,
|
gammaCorrectBri = false,
|
||||||
@ -768,6 +771,7 @@ class WS2812FX {
|
|||||||
color_wheel(uint8_t),
|
color_wheel(uint8_t),
|
||||||
color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255),
|
color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255),
|
||||||
color_blend(uint32_t,uint32_t,uint16_t,bool b16=false),
|
color_blend(uint32_t,uint32_t,uint16_t,bool b16=false),
|
||||||
|
color_add(uint32_t,uint32_t),
|
||||||
currentColor(uint32_t colorNew, uint8_t tNr),
|
currentColor(uint32_t colorNew, uint8_t tNr),
|
||||||
gamma32(uint32_t),
|
gamma32(uint32_t),
|
||||||
getLastShow(void),
|
getLastShow(void),
|
||||||
|
@ -193,10 +193,16 @@ void /*IRAM_ATTR*/ WS2812FX::setPixelColorXY(float x, float y, byte r, byte g, b
|
|||||||
const uint16_t rows = SEGMENT.virtualHeight();
|
const uint16_t rows = SEGMENT.virtualHeight();
|
||||||
|
|
||||||
if (aa) {
|
if (aa) {
|
||||||
uint16_t xL = floorf(x * (cols-1));
|
float fX = x * (cols-1);
|
||||||
uint16_t xR = ceilf(x * (cols-1));
|
float fL = floorf(x * (cols-1));
|
||||||
uint16_t yT = floorf(y * (rows-1));
|
float fR = ceilf(x * (cols-1));
|
||||||
uint16_t yB = ceilf(y * (rows-1));
|
float fY = y * (rows-1);
|
||||||
|
float fT = floorf(y * (rows-1));
|
||||||
|
float fB = ceilf(y * (rows-1));
|
||||||
|
uint16_t xL = fL;
|
||||||
|
uint16_t xR = fR;
|
||||||
|
uint16_t yT = fT;
|
||||||
|
uint16_t yB = fB;
|
||||||
uint32_t cXLYT = getPixelColorXY(xL, yT);
|
uint32_t cXLYT = getPixelColorXY(xL, yT);
|
||||||
uint32_t cXRYT = getPixelColorXY(xR, yT);
|
uint32_t cXRYT = getPixelColorXY(xR, yT);
|
||||||
uint32_t cXLYB = getPixelColorXY(xL, yB);
|
uint32_t cXLYB = getPixelColorXY(xL, yB);
|
||||||
@ -204,30 +210,30 @@ void /*IRAM_ATTR*/ WS2812FX::setPixelColorXY(float x, float y, byte r, byte g, b
|
|||||||
|
|
||||||
if (xL!=xR && yT!=yB) {
|
if (xL!=xR && yT!=yB) {
|
||||||
// blend TL pixel
|
// blend TL pixel
|
||||||
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, sqrtf((x - floor(x))*(y - floorf(y)))*UINT16_MAX, true);
|
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, sqrtf((fR - fX)*(fB - fY))*UINT16_MAX, true);
|
||||||
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
||||||
// blend TR pixel
|
// blend TR pixel
|
||||||
cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, sqrtf((ceilf(x) - x)*(y - floorf(y)))*UINT16_MAX, true);
|
cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, sqrtf((fX - fL)*(fB - fY))*UINT16_MAX, true);
|
||||||
setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT));
|
setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT));
|
||||||
// blend BL pixel
|
// blend BL pixel
|
||||||
cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, sqrtf((x - floor(x))*(ceil(y) - y))*UINT16_MAX, true);
|
cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, sqrtf((fR - fX)*(fY - fT))*UINT16_MAX, true);
|
||||||
setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB));
|
setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB));
|
||||||
// blend BR pixel
|
// blend BR pixel
|
||||||
cXRYB = color_blend(RGBW32(r,g,b,w), cXRYB, sqrtf((ceilf(x) - x)*(ceil(y) - y))*UINT16_MAX, true);
|
cXRYB = color_blend(RGBW32(r,g,b,w), cXRYB, sqrtf((fX - fL)*(fY - fT))*UINT16_MAX, true);
|
||||||
setPixelColorXY(xR, yB, R(cXRYB), G(cXRYB), B(cXRYB), W(cXRYB));
|
setPixelColorXY(xR, yB, R(cXRYB), G(cXRYB), B(cXRYB), W(cXRYB));
|
||||||
} else if (xR!=xL && yT==yB) {
|
} else if (xR!=xL && yT==yB) {
|
||||||
// blend L pixel
|
// blend L pixel
|
||||||
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, (x - floor(x))*UINT16_MAX, true);
|
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, (fR - fX)*UINT16_MAX, true);
|
||||||
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
||||||
// blend R pixel
|
// blend R pixel
|
||||||
cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, (ceilf(x) - x)*UINT16_MAX, true);
|
cXRYT = color_blend(RGBW32(r,g,b,w), cXRYT, (fX - fL)*UINT16_MAX, true);
|
||||||
setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT));
|
setPixelColorXY(xR, yT, R(cXRYT), G(cXRYT), B(cXRYT), W(cXRYT));
|
||||||
} else if (xR==xL && yT!=yB) {
|
} else if (xR==xL && yT!=yB) {
|
||||||
// blend T pixel
|
// blend T pixel
|
||||||
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, (y - floorf(y))*UINT16_MAX, true);
|
cXLYT = color_blend(RGBW32(r,g,b,w), cXLYT, (fB - fY)*UINT16_MAX, true);
|
||||||
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
setPixelColorXY(xR, yT, R(cXLYT), G(cXLYT), B(cXLYT), W(cXLYT));
|
||||||
// blend B pixel
|
// blend B pixel
|
||||||
cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, (ceil(y) - y)*UINT16_MAX, true);
|
cXLYB = color_blend(RGBW32(r,g,b,w), cXLYB, (fY - fT)*UINT16_MAX, true);
|
||||||
setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB));
|
setPixelColorXY(xL, yB, R(cXLYB), G(cXLYB), B(cXLYB), W(cXLYB));
|
||||||
} else {
|
} else {
|
||||||
// exact match (x & y land on a pixel)
|
// exact match (x & y land on a pixel)
|
||||||
|
@ -182,6 +182,35 @@ void WS2812FX::service() {
|
|||||||
_triggered = false;
|
_triggered = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// anti-aliased normalized version of setPixelColor()
|
||||||
|
void /*IRAM_ATTR*/ WS2812FX::setPixelColor(float i, byte r, byte g, byte b, byte w, bool aa)
|
||||||
|
{
|
||||||
|
if (i<0.0f || i>1.0f) return; // not normalized
|
||||||
|
|
||||||
|
if (aa) {
|
||||||
|
float fC = i * (SEGLEN-1);
|
||||||
|
float fL = floorf(i * (SEGLEN-1));
|
||||||
|
float fR = ceilf(i * (SEGLEN-1));
|
||||||
|
uint16_t iL = fL;
|
||||||
|
uint16_t iR = fR;
|
||||||
|
uint32_t cIL = getPixelColor(iL);
|
||||||
|
uint32_t cIR = getPixelColor(iR);
|
||||||
|
if (iR!=iL) {
|
||||||
|
// blend L pixel
|
||||||
|
cIL = color_blend(RGBW32(r,g,b,w), cIL, (fR - fC)*UINT16_MAX, true);
|
||||||
|
setPixelColor(iL, R(cIL), G(cIL), B(cIL), W(cIL));
|
||||||
|
// blend R pixel
|
||||||
|
cIR = color_blend(RGBW32(r,g,b,w), cIR, (fC - fL)*UINT16_MAX, true);
|
||||||
|
setPixelColor(iR, R(cIR), G(cIR), B(cIR), W(cIR));
|
||||||
|
} else {
|
||||||
|
// exact match (x & y land on a pixel)
|
||||||
|
setPixelColor(iL, r, g, b, w);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setPixelColor((uint16_t)roundf(i * (SEGLEN-1)), r, g, b, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
|
||||||
{
|
{
|
||||||
uint8_t segIdx = SEGLEN ? _segment_index : _mainSegment;
|
uint8_t segIdx = SEGLEN ? _segment_index : _mainSegment;
|
||||||
@ -887,6 +916,24 @@ uint32_t IRAM_ATTR WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint1
|
|||||||
return RGBW32(r3, g3, b3, w3);
|
return RGBW32(r3, g3, b3, w3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* color add function that preserves ratio
|
||||||
|
* idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule
|
||||||
|
*/
|
||||||
|
uint32_t WS2812FX::color_add(uint32_t c1, uint32_t c2)
|
||||||
|
{
|
||||||
|
uint32_t r = R(c1) + R(c2);
|
||||||
|
uint32_t g = G(c1) + G(c2);
|
||||||
|
uint32_t b = B(c1) + B(c2);
|
||||||
|
uint32_t w = W(c1) + W(c2);
|
||||||
|
uint16_t max = r;
|
||||||
|
if (g > max) max = g;
|
||||||
|
if (b > max) max = b;
|
||||||
|
if (w > max) max = w;
|
||||||
|
if (max < 256) return RGBW32(r, g, b, w);
|
||||||
|
else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fills segment with color
|
* Fills segment with color
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user