3: Using input to control the palette generation

In the previous part, all examples used Unity's built-in Random.Range function to generate random color palettes. While it showed that random input can make decent palettes, a more interesting way to procedurally generate color palettes is using input variables.

There are several reasons why you'd want to generate a palette based on input rather than randoms.
- The same input can generate the same palette again at any time.
- Possible palettes can be better curated by the designer.
- Palettes can be responsive to, for example, player input or time of day.

You can download a package with all below code here.

Examples of palettes generated using input color

Same input, same result

Structurizing the procedural palette generation in a way that a certain set of input variables will always result in exactly 1 palette, can be utilized to create predictable palettes that are logical in certain situations. Doing this is fairly simple: simply replace any Random.Range function by (a calculation utilizing) an input variable.
Any kind of input can be used for this, for example a single color, a handful of floats, or the current time. This allows for, among other things, user input.

float mainHue = inputColor.h;
float hueShift = inputColor.s * inputColor.l * .5f - .2f;
float mainSaturation = inputColor.s;
float saturationShift = inputColor.s * .1f * (inputColor.s + inputColor.l);
float mainLuminance = inputColor.l;
float luminanceShift = Mathf.Sin(inputColor.l * 31) * .07f;

//then generate color with these variables and the calculations of the previous part

Same time, same result

A value that I like to use as input for generation is UNIX time, as it is the same across different machines. When generating the color palette using it, two different people on different computers will get the same palette, regardless of their exact input.

//get UNIX timestamp
System.DateTime epochStart = new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc);
int unixTime = (int)(System.DateTime.UtcNow - epochStart).TotalSeconds;
//then determine some variables from that
float mainHue = (unixTime % 60) * .016f;
float hueShift = Mathf.Sin(unixTime * .02f * Mathf.PI) * .1f;
float mainSaturation = .3f + Mathf.PingPong(unixTime * .015f, 5) * .1f;
float saturationShift = Mathf.PingPong(unixTime * .007f, .1f) + .01f;
float mainLuminance = .5f + Mathf.Cos(unixTime * .1f) * .25f;
float luminanceShift = (.5f - mainLuminance) * .2f;

//then generate color with these variables and the calculations of the previous part

How to use the input in an impactful way

This largely depends on what your input variables are and what you want to achieve with their use. For example, if you're creating a dungeon crawler kind of game and use health as an input, it might make sense to pull hue closer to red or saturation and lightness closer to zero when health is low. This really is a designer's playground, there are no good or bad ways to use your input.