Mixing colors like paint

Godot Version

Godot 4.6

Question

I just want to make a system to mix an array of colors as if it was paint,

ex: yellow+blue=green

but nothing has worked. here is the code I came up with, it only works in cases with rgb

example red+blue=purple but yellow+blue=white

func mixcolors(colors:Array):
	var output:Color
	var step = 0
	for c in colors:
		if c is Color:
			if step == 0:
				output = c
			else:
				output = (output/2 + c/2).clamp()
			step += 1
			
	return output

Please help

Thanks!

There is Color::blend(). Would that work for you?

I am unsure if I am using it correctly, every way I try to use it it just returns whatever color I put inside,

color(blue).blend(yellow) just returns yellow.

:confused:

The colors can not be properly mixed using RGB. That is because the amount of sensors in the eyes are not the same for r g and b.
You should research based on that.

What you want is subtractive color mixing. Mathematically pure subtractive mixing is just multiplication. This is perceptually not satisfying in many cases but you can start by that as it’s trivial to implement. Note that your primaries in the pure subtractive model are not blue and red but cyan and magenta, and mixing blue and yellow will result in black instead of green.

There’s a formula that emulates real world mixing a bit better so it might be acceptable for your use case:

mixed = 1.0 - sqrt(((1.0 - color1) ** 2.0 + (1.0 - color2) ** 2.0) / 2.0)

When doing it with Godot’s Color object, for best results you might want to convert input colors to linear color space and then convert the result back to srgb color space.

Mixing green from blue and yellow will still be a problem though.

2 Likes

There’s apparently some new-ish algorithm that emulates paint mixing in perceptually satisfying way.
I haven’t looked into it but here’s the siggraph presentation:

EDIT: There’s Python source code available under CC BY-NC 4.0 license:

2 Likes

I found a way, I noticed @normalized ā€˜s second idea came with some kind of copyright thing so I dug deeper then I did at first,

my solution was just using hsv

but thanks for helping!

How can hsv emulate subtractive mixing? I’m curious.

It would be nice for people coming after you with the same question if you showed the solution.

2 Likes