BETTER COLOR3 - Enhanced colour manipulation module

MODULE API

from default Color3

These functions originate from default Color3, where their use is exactly the same.

color3.new(r, g, b)
color3.fromRGB(r, g, b)
color3.fromHSV(hue, saturation, value)
color3.fromHEX(hex)

new to color3

These functions aren’t present in the default Color3 module

color3.fromYUV(Luminance, Blue_Chrominance, Red_Chrominance)
color3.fromBytepack(n, offset)

PRESESTS

color3.presets contains a list of already made colours:

white → 255 255 255
black → 0 0 0
red → 255, 0, 0
green-> 0, 255, 0
blue → 0, 0, 255
purple → 255, 0, 255
cyan → 0, 255, 255
yellow → 255, 255, 0

METHODS

ARITHMETIC

(all arithmetic methods by default clamp the new RGB values to 0-255)

color3 + color3: color3
Adds the R, G and B values of the two color3 values.
Accepts default Color3 as well as numbers, where if a number is added, it would add the number to all RGB values.

color3 - color3: color3
Subtracts the R, G and B values of the two color3 values.
Accepts default Color3 as well as numbers, where if a number is subtracted, it would subtract the number from all RGB values.

color3 * color3: color3
Multiplies the R, G and B values of the two color3 values.
Accepts default Color3 as well as numbers, where if a number is multiplied, it would multiply the number with all RGB values.

color3 / color3: color3
Devides the R, G and B values of the two color3 values.
Accepts default Color3 as well as numbers, where if a number is devided, it would devide the RGB values by the number.

color3 ^ color3: color3
Powers the R, G, B values of input A to the number or RGB values of input B.
Accepts default Color3 as well as numbers, where if a number is devided, it would devide the RGB values by the number.

-color3
Inverts the color3, where if it was 100, 255, 255, it’s now 155, 0, 0

color3 % color3: color3
Returns the average of the two color3 values. Accepts the default Color3, but does not accept numbers.

#color3
Returns the hex value of the color3

color3 == color3
Returns true if the two color3 values are identical. ONLY accepts color3 values.

FUNCTIONS

from default Color3

These functions originate from default Color3, where their use is exactly the same.
color3:ToHSV()
color3:ToHex()
color3:Lerp(color, alpha)

new to color3

These functions aren’t present in default Color3 module

color3:Quadlerp(color, alpha)
Lerps self to color by alpha, uses the equation alpha ^ alpha
Accepts both color3 and Color3 inputs as color input.

color3:Sinelerp(color, alpha)
Lerps self to color by alpha, uses the equation sin(alpha * π * 0.5)
Accepts both color3 and Color3 inputs as color input.

color3:ToGrayscale()
Returns the grayscale version of the color3. Grayscale is NOT the average of the RGB values.

color3:ToAverage()
Returns the average version of the color3, where all RGB values are the average of the previous RGB values.

color3:Bytepack(offset)
Packs the RGB values into a 32bit number.
@CoderHusk did a great job explaining it here

color3:RotateHue(degrees)
Returns a new color3, with the hue changed by degrees

color3:GetYUV()
Returns Y (Luminance), U (Blue Chrominance) and V (Red Chrominance) from the color3 object.

MENTION

color3() returns the default Color3 value of the color3 object.

LINK

here

If you got any ideas for functions that the color3 module is missing, please note them in the thread!

25 Likes

Added two more methods:

tostring(color3) returns a string in the format:

"red, green, blue"

concatting a color3 to a value would also convert it into a string.

The source code above would print out: “99, 12, 120 test

1 Like

minor fix 2

Fixed a miscalculation in color3:ToGrayscale()

Added:
:GetRedChrominance() gets the Red Chrominance of the color3.
:GetBlueChrominance() gets the Blue Chrominance of the color3.
:GetLuminance() gets the Luminnce of the color3.

1 Like

minor fix 3

added

color3:ToYUV()
Returns Y (Luminance), U (Blue Chrominance) and V (Red Chrominance)

color3:FromYUV(Luminance, Blue_Chrominance, Red_Chrominance)
Returns a new color3 object from Luminance, blue chrominance and red chrominance

removed

GetRedChrominance()
GetBlueChrominance()
GetLuminance()

1 Like

update

:Lerp(color, alpha) now accepts default Color3s as inputs.

new function methods

Quadlerp(color, alpha)
Sinelerp (color, alpha)

As the names suggest, Quad and Sine lerps used sine and quadratic equation.


This represents with y being ratio of colour and x being alpha.

Green: default Lerp()
Red: Quadlerp()
Blue: Sinelerp()

3 Likes

update 2

color3.colorSpin() returns an iterator function, which results: degrees, color3

inputs

startingDeg: number?, increment: number?, value: number?, saturation: number?

outputs

color3

color3.tweenIterator()

inputs

a: Color3 | color3, b: Color3 | color3, style: "Sine"|"Quad"|"Line", increment: number?

outputs

color3

color3.random()

inputs

seed: number?

outputs

color3

color3.noise()

inputs

x: number,
y: number,
xSeed: number?
ySeed: number?

outputs

color3

NOTE for color3.noise():
R is generated using the X seed
G is generated using the Y seed
B is generated using (X * Y) ^ 0.5 with the sum of both seeds used

3 Likes

version 1.1 [update 3]

Reffering to later updates by their version, not by the update index.

CHANGES

Metamethod: color3 % color3 now returns a new color3 object, where the RGB values of the two color3 objects in the method have the bitwise AND operation performed on them.

Their previous use which was to get the average value between the two color3 objects has been given to function:
color3:LerpAverage()
INPUTS

self: color3, color: color3

OUTPUTS

color3

For the same usage, color3:Lerp() can be used, where alpha (argument 2) is 0.5.

Metamethod: color3 // color3 now exists, returning the OR bitwise operation, basically combining the two RGB values.

Also color3.fromColor3() has been added, where the input is a default Color3 value.

color3.toHSV() has been fixed, returning the intended tuple:

Hue (number), Saturation (number), Value (number)

Previously, the HSV values were then packed back into a color3 object, where H → R, S → G, V → B.
There was no reason for this bug, it was just a typo basically.

Also when performing the metamethod color3 ^ color3, previously it would perform the bitwise XOR operations and return a new color3 pbject, but now if one of the values is under 1 and is a float, it would perform the traditional power, where the R, G and B values of the color3 of the operation are powered to the number inputted. Since it not considering any numbers above 1 as inputs for a power, this can only really be used to root and/or negatively power the values.

NEW CONFIG SETTINGS

As of now, there is only 1 configuration:

color3.config.setDisplay()
INPUTS

f: (color3) -> (string)

This function simply sets the function used when converting the color3 object into a string to the function inputted (f). By default the function is still the same as it was prior to this update.

VISUAL CHANGES

  • type color3 (exported) exists, making typechecking a bit easier.
  • source code in the module cleaned up somewhat
  • all functions now have typechecking.

other functions

color3:set() now exists, once inputted another color3 object, it would copy the data to self, and then delete the color3 object inputted.

color3:Remove() simply removes the object (by setting metatable to nil)

color3:Clone() returns a new color3 object, with same RGB values as self.

2 Likes

I’m out of things to add to the module :sob:

If anyone has any ideas on what to add that isn’t in the module please tell me them!!

3 Likes

version 1.2

Perfoming the modulo % opperation between a color3 and another color3, Color3 or number would perform the standard modulo equation, where self’s RGB values have the modulo operation performed on them with the other RGB values, where new R = self.R % other.R. If other is a number, the same number would be performed on all RGB values.

Performing the floor // would work just as the modulo method but using the // arithmetic operation.

Performing the power ^ would work jsut as module method but using the ^ arithmetic operation.
(prior to this update, if the other input was less than 1, then it would power, if not then it would use the xor operation, now that’s been replaced by color:bxor())

new functions for color3 objects

:invert()
Returns a new color3, with the binary NOT operation performed on the RGB values.

:band(other: color3|Color3|number)
Returns a new color3, with the binary AND operation performed between self and other.

:bor(other: color3|Color3|number)
Returns a new color3, with the binary OR operation performed between self and other.

:bxor(other: color3|Color3|number)
Returns a new color3, with the binary XOR operation performed between self and other.

1 Like

I feel weird… Why is there no reply, only updates…

why is this thread so lonely…

is there something i am supposed to know and I don’t?

4 Likes

Making modules can be fun. But before you upload it as a public resource, ask these questions to yourself:

  • What more does this have than the thing I’m trying to improve?
  • Does this solve anything?
  • Why would people use it? Why not?
  • Does it handle multiple use cases, or just one?
  • Is it making things easier, or harder?

Let me elaborate:

Do you think anybody would use this? I have no idea what “chrominance” is…

This is so specific, I don’t think you need to add random functions like this. Instead, it would be good to generalize methods, making the programmer add a bit more code, but also allowing it to be used for many different things apart from just one thing.

2 Likes

This module makes Color3 easier by allowing arithmetic operations to be conducted on it, aswell as bitwise operations.

Also for specific functions, I really only made them because there wasn’t much else that I thought to add at that time, functions such as color3.tweenInterator() really only came because I learnt what iterator functions were whilst developing the module.

Also Red & Blue chrominance, alongside luminance, are explained in this video here, which is where I got the idea for the function from and is where I’d likely make more functions for calculations in the video:

It can also have multiple use cases, can be used to replace the default Color3 (although when setting values that only accept Color3’s, the color3 would have to be called)

Thanks for reply though! I’ll try make function names better and more useful! :cool:

2 Likes

version 1.2.2

A fix (and minor additions) to new functions in 1.2

The bitwise functions of :band(), :bor(), bxor() now take in a tuple instead of a singular output, color3’s, Color3’s and numbers are still only the valid types for this function.

New bitwise function :bnand(), like the other bitwise operations, takes in a tuple. The output is similar to the output of :band() but reversed.

REMOVED FUNCTIONS

color3:AverageLerp() depricated in favour of color3:Lerp()

RENAMED FUNCTIONS

color3.noise() renamed to: color3.fromNoise()
color3.random() renamed to color3.fromRandom()

YUV fix

Functions: color3:fromYUV() and color3:toYUV() have been corrected to a more accurate YUV calculation model source

Previously, outdated calculations were used for the YUV conversion, which didn’t align with each other, meaning that if a color3 is converted into a yuv and converted back, it would be far different than the original color3.

I’m considering adding metamethods for <, >, >= & <= metamethods, but since color3 has 3 values, I’ll hold a vote on what value should be used to compare the RGB values:

  • Luminance / Grayscale of the RGB
  • Sum of R, G & B
  • Average of R, G & B

0 voters

Nice module, will you consider adding this as a package to wally? that would be very useful

version 1.3

NOTE: boolean operators only work between color3 values, trying to use them between a color3 and a traditional Color3 value will result in an error.

NEW METAMETHODS

As promised, the methods <, >, ==, >= & <= have been added.

Function renames

color3:band()color3:Conjunction()
color3:bor()color3:Disjunction()
color3:inverse()color3:negate()
color3:bxor()color3:E_Disjunction()
color3:bnand()color3:N_Conjunction

color3:Lerp()color3:LerpRGB()

Removed functions

color3:SineLerp() and color3:QuadLerp() have been replaced by color3:LerpRGB(), where as a third input, the Lerp function takes in a string. Either "linear", "quad" or "sine"
color3:tweenIterator() has been removed, not yet replaced with a new method but I’m considering using the __iter() metamethod for a replacement.

Other changes

Lerp is now calculated without switching to traditional Color3 to do the :Lerp() operation.

Soon convertions via HUV will be done directly with the color3 module, instead of its current method of switching to the traditional Color3 value to perform Color3:ToHUV() or Color3:FromHUV()

New update will be soon, just don’t know what to add.

If any of you got ideas on what the module is missing, or what the module can do better, then please make a comment here!

I have no idea why this resource is so dead. There are tons of useful color3 operations that most libraries have on other engines, such as color * color.

But there’s one thing…

I would use this module to work with EditableImages, but they work with pure RGBA values, so as a developer myself, I don’t really see myself using this.

You could maybe try to integrate this to support raw RGBA numbers, but I honestly don’t think it would be worth it since, well, numbers have math.

3 Likes

I have an old project that can run kernel effects on a canvas with RGB (no A) values, I may revisit that project and make a module for it using BETTER COLOR3 and my existing code.

Here’s that project: