Ashley I'm confused about the ColorValue expression, which returns an integer that contains negative numbers. Is there a way to convert it to a regular color value?
For example, Allow expression input parameters:
ColorValue("R")
ColorValue("G")
ColorValue("B")
ColorValue("A")
Converting a colorValue back to RGB 255:
R = int((-colorValue / 2^38) % 1025 * 255 / 1023)
G = int((-colorValue / 2^24) % 1025 * 255 / 1023)
B = int((-colorValue / 2^10) % 1025 * 255 / 1023)
A = int((-colorValue) % 1025 * 255 / 1023)
Converting a colorValue back to RGB 255: R = int((-colorValue / 2^38) % 1025 * 255 / 1023) G = int((-colorValue / 2^24) % 1025 * 255 / 1023) B = int((-colorValue / 2^10) % 1025 * 255 / 1023) A = int((-colorValue) % 1025 * 255 / 1023)
I tested using some colors but the formula didn't give the expected results
-> System: Set colorValue to Sprite.ColorValue
const colorValue = runtime.globalVars.colorValue; runtime.globalVars.r = Math.round((-colorValue / Math.pow(2, 38)) % 1025 * 255 / 1023); runtime.globalVars.g = Math.round((-colorValue / Math.pow(2, 24)) % 1025 * 255 / 1023); runtime.globalVars.b = Math.round((-colorValue / Math.pow(2, 10)) % 1025 * 255 / 1023); runtime.globalVars.a = Math.round((-colorValue) % 1025 * 255 / 1023);
White (255, 255, 255) // -281492157629439 -> (255,4,196,60) Dark(10, 20, 30) // -10996458578943 -> (10,116,220,36) Grey(128, 128, 128) // -141295868185599 -> (128,122,218,37) Red(255, 0, 0) // -281474976711679 -> (255,4,192,63) Green(0, 255, 0) // -17179870207 -> (0,255,4,251) Blue(70, 59, 222) // -77244652187647 -> (70,216,94,161)
Develop games in your browser. Powerful, performant & highly capable.
yea you are right, it seems to give incorrect results. Let me check c3 source to see how they generate it
const ALPHAEX_SHIFT = 1024; const ALPHAEX_MAX = 1023; const RGBEX_SHIFT = 16384; const RGBEX_MAX = 8191; const RGBEX_MIN = -8192; C3.GetRValue = function GetRValue(rgb) { if (rgb >= 0) return (rgb & 255) / 255; else { let v = Math.floor(-rgb / (RGBEX_SHIFT * RGBEX_SHIFT * ALPHAEX_SHIFT)); if (v > RGBEX_MAX) v -= RGBEX_SHIFT; return v / 1024 } } ; C3.GetGValue = function GetGValue(rgb) { if (rgb >= 0) return ((rgb & 65280) >> 8) / 255; else { let v = Math.floor(-rgb % (RGBEX_SHIFT * RGBEX_SHIFT * ALPHAEX_SHIFT) / (RGBEX_SHIFT * ALPHAEX_SHIFT)); if (v > RGBEX_MAX) v -= RGBEX_SHIFT; return v / 1024 } } ; C3.GetBValue = function GetBValue(rgb) { if (rgb >= 0) return ((rgb & 16711680) >> 16) / 255; else { let v = Math.floor(-rgb % (RGBEX_SHIFT * ALPHAEX_SHIFT) / ALPHAEX_SHIFT); if (v > RGBEX_MAX) v -= RGBEX_SHIFT; return v / 1024 } } ; C3.GetAValue = function GetAValue(rgb) { if (isNegativeZero(rgb)) return 0; else if (rgb >= 0) return 1; else { const v = Math.floor(-rgb % ALPHAEX_SHIFT); return v / ALPHAEX_MAX } }
Thanks! it can works.
This function gets the color value from 0-1, which needs to be converted to 0~255.
function convertTo255(value) { return Math.round(value * 255); }
I make a test c3p.
cdn.discordapp.com/attachments/1195261473711194142/1195339973730246706/ColorValueConvert.c3p
const ALPHAEX_SHIFT = 1024; const ALPHAEX_MAX = 1023; const RGBEX_SHIFT = 16384; const RGBEX_MAX = 8191; const RGB_MASK = [255, 65280, 16711680]; const RGB_SHIFT = [0, 8, 16]; const RGB_FACTOR = [RGBEX_SHIFT * RGBEX_SHIFT * ALPHAEX_SHIFT, RGBEX_SHIFT * ALPHAEX_SHIFT, ALPHAEX_SHIFT]; function getColorValue(rgb, index) { if (rgb >= 0) { return (rgb & RGB_MASK[index]) >> RGB_SHIFT[index]; } else { let v = Math.floor(-rgb % RGB_FACTOR[index] / RGB_FACTOR[index] / ALPHAEX_SHIFT); if (v > RGBEX_MAX) v -= RGBEX_SHIFT; return v / 1024; } } function GetRValue(rgb) { return getColorValue(rgb, 0) / 255; }; function GetGValue(rgb) { return getColorValue(rgb, 1) / 255; }; function GetBValue(rgb) { return getColorValue(rgb, 2) / 255; }; function isNegativeZero(n) { return Object.is(n, -0); } function GetAValue(rgb) { if (isNegativeZero(rgb)) return 0; else if (rgb >= 0) return 1; else { const v = Math.floor(-rgb % ALPHAEX_SHIFT); return v / ALPHAEX_MAX; } }; function convertTo255(value) { return Math.round(value * 255); }
Use:
//------------------------------------------------ // Set Global Var //------------------------------------------------ const colorValue = runtime.globalVars.colorValue; runtime.globalVars.r = convertTo255(C3.GetRValue(colorValue)); runtime.globalVars.g = convertTo255(C3.GetGValue(colorValue)); runtime.globalVars.b = convertTo255(C3.GetBValue(colorValue));
Any chance we can get an expression version so I can set text? :)
Had another look at getting cleaner formulas than what C3 uses internally and here we are:
Looks like c3 rgb values are 10bit +1? alpha is 10bit. Anyways here's the conversions.
red = round(int(-color / 2^38) % 2048 * 255/ 1024) green = round(int(-color / 2^24) % 2048 * 255 / 1024) blue = round(int(-color / 2^10) % 2048 * 255 / 1024) alpha = round(-color % 1024 * 255/ 1023)
Tested with thousands of random colors and it works flawlessly so far.
Note:
C3's rgb expressions only return negative numbers which mean the colors are stored in 10bit per component, and works with the above formulas.
If you're curious, positive values mean it's a color with 8bit per component color=r*256*256*256+g*256*256+b*256+a where each component is a value 0-255. C3 still supports colors like that but you'd have to generate them manually. Also you'd need different formulas to extract the components. However that's easily found online if needed.