If you can lerp twp colours, you can lerp “n” colours. It’s just a case of where the colour-space conversion takes place.
If we have ten different colours, then we need ten values to represent how much of each to use. In order to ensure we don’t end up with “too much” mixing, we need the vector representing how much of each to be normalized. This prevents the case of having two colours “active” at the same time.
With a plain linear lerp this would be easy as you could throw all your colours into a matrix, and do the lerp using linear algebra. However, we can do something similar by converting to the colour space before the lerp. I’m going to approximate with an HSV lerp here.
Example:
import mathutils
COLORS = [
[1, 0, 0], # Red
[0, 1, 0], # Green
[0, 0, 1], # Blue
[1, 1, 0], # Yellow
[1, 0, 1], # Pink
]
def to_conv_space(col):
'''Convert into the color space used to lerping. In this case, hsv'''
return mathutils.Vector(mathutils.Color(col).hsv)
def from_conv_space(col):
'''Convert from the color space used for lerping back into rgb'''
out = mathutils.Color()
out.v = col[2]
out.s = col[1] # Always set saturation before hue otherwise hue may be discarded
out.h = col[0]
return out
def normalize(vec):
'''Manhatten normalize so that the vector so that the sum is 1'''
vec_len = sum(v for v in vec)
return [v/vec_len for v in vec]
def matrix_multiply(mat, vec):
'''Multiplies a matrix by a vector. Matrix columns must match vector length'''
individual_values = [c*vec[i] for i, c in enumerate(mat)]
return sum(individual_values, mathutils.Vector())
hsv_colors = [to_conv_space(c) for c in COLORS] # Only needs to run at game start.
# How much of each color we want. This should be normalized on the nth norm.
# clearly this vector isn't because we've specified both red and green
our_choice = [1, 1, 0, 0, 0]
our_choice = normalize(our_choice)
# [0.5, 0.5, 0, 0, 0] - whew, no more "extra" colors.
# We are aiming for half-way between the first two colours, in this case
# halfway between red and green.
# muliply the color matrix, which is effectively our "lerp"
out_color_in_conv_space = matrix_multiply(hsv_colors, our_choice)
# Convert back into RGB
out_color_in_rgb = from_conv_space(out_color_in_conv_space)
print(out_color_in_rgb)
# [1, 1, 0] which is yellow, which is halfway between red and green in HSV-space
Because we only need to do the inverse colour transform once (assuming the set of colours doesn’t change), this method should be able to be made reasonably fast. It would be even faster if we did our matrix math inside numpy - but I have yet to learn the numpy API.