Here’s my first completely solo pattern, for the sunrise challenge.
While I initially intended it to be a 2D pattern as I am using it on lights around a bed, I liked the look of a 1D pattern, across the 0-1 world of the render2D pattern. I’m sure there is a more logical way of organizing the render2D/render3D sections.
// my first fully independent pattern, for the sunrise challenge.
// there are 3 different main variables,
// 1) the curve for the increasing brightness, which uses the Spread (essentially the final total width of bright pixels)
// and the Sharpness, which is the focal nature of initial bright pixels. This is a function of time. Currently time loops, but modifying the t1 variable could allow
// for a run-once type scenario
// 2) the hue, set to hueSun for within the sun, and hueEdges for the edges, and between the two uses a coarse gradient between the two. This works for yellow-red, as
// they are neighbours on the HSV color spectrum, however a more sophistocated gradient formula would be needed for non-neighbour colors.
// 3) the sun radius, increases over time, and then the center of this is desaturated to make it white
// for all of this example, the sun rises centred on the y-axis. This could be easily changed in the render2D function.
// While my physical implementation is a 3D model, I found the 2D rendering works quite nicely as is, and wouldn't likely benefit from the 3rd dimension
export var hueSun = .10, hueEdges = 0.01 //0.05, 0.001
export var sharpness = 2, spread = 10
var location = 0.5 // the centre of the sunrise
export var t1 // main time cycling variable, from 0 to 1
export var sunRadius = 0
var rimToWhite = 0.1
//make a sharpness UI slider to spread the color across the whole strip or sharpen to a spot
export function sliderSpread(v) {
spread = v * 10 // give a range of 0-10
}
// make a function for how sharp the initial pinpoint of sunrise will be, range 0-3
export function sliderSharpness(v) {
sharpness = v * 3
}
// over-simplified, given that the HSV colorspace almost allows for a reasonable sunset color gradient. Ideally, this would be a proper gradient calculation
// this will be fed a value from 0 to 0.5. at 0, it should return hueSun ,and at 0.5 (or more, error correction), it should return hueEdges
function sunsetGradient(distFromSun) {
var returnHue = hueSun
if (distFromSun <=0) returnHue = hueSun
else if (distFromSun >=0.4) returnHue = hueEdges
else {
// safely have a value of cDist between 0 and 0.4. calculate slope of higher-lower/horizontal, plus lower, to give line between higher and lower, over the given horizontal distance.
returnHue = ((hueEdges-hueSun)/0.4)*distFromSun + hueSun
}
return returnHue
}
// time loops every 65.54*interval seconds, and interval 0.015 = 1 second apprx.
// the clamp formula with time causes the sun size growth to lag 0.1 time unit behind the increase in brightness
export function beforeRender(delta) {
t1 = time(0.5)
sunRadius = (clamp(t1-0.1,0,1))*0.35
}
export function render2D(index, x, y) {
var cDist = abs(location-y)
var distFromSun = clamp((cDist-sunRadius),0,1)
var sat
var hue
// y=-2*(0.5*x)^2 + x
var va = - spread * pow(((1/spread)*cDist), sharpness) + (t1)
va = clamp(va,0,1) //clamp the value between zero and one
// calculate white (desaturated) centre of sun
if (cDist<(sunRadius-rimToWhite)) {
// from cDist=0 to cDist=sunRadius-rimToWhite, gradient between 0.5 and 1 sat=(1/(radius-rimToWhite))*cDist
sat=((1-0.5)/(sunRadius-rimToWhite))*cDist + 0.5
}
else sat = 1
// calculate gradient,as a functin of the distance from the sun centre.
hue = sunsetGradient(distFromSun)
hsv(hue, sat , va)
}
export function render3D(index, x, y, z) {
render2D(index,x,y)
}
edit: fixed my math on the value (brightness) equation.
I would still sort of like the first color to be the edge (red) color, then fade into the yellow, then progress as already coded, but that’s a problem for another day.