I’m working on a platform game with large, vertically scrolling levels and wanted a simple parallax sky effect in the background. Using a large texture would be impractical as the levels are going to be considerably taller than 2048 pixels. So I wrote a shader for shading between multiple colours. You set 5 colours, the percentage points (from scale 0.0 to 1.0) at which you’d like one to fade in the next, the centre point at which the gradient starts, and the shape of the gradient (circle, elliptical, or linear gradients are possible). I thought I’d share it here in case someone else has a use for it. This could be adapted for all sorts of things, eg to make colourful text etc.
The image below is my attempt at a sunset sky. It would look pretty good (in a cartoony way) with some clouds in front of it.
--# Main
-- MultiStop Colour Gradients
function setup()
print ("Drag your finger to set the gradient centre")
print ("Pull down this output window to access more settings")
Gradient.setup()
parameter.number("GradientAspect", 0, 2, 0.5)
parameter.number("Step1", 0, 1, 0.9)
parameter.number("Step2", 0, 1, 0.3)
parameter.number("Step3", 0, 1, 0.2)
parameter.number("Step4", 0, 1, 0.1)
parameter.number("Step5", 0, 1, 0.05)
parameter.color("Color1",
color(31, 27, 53, 255))
parameter.color("Color2",
color(0, 198, 255, 255))
parameter.color("Color3",
color(228, 207, 225, 255))
parameter.color("Color4",
color(254, 0, 0, 255))
parameter.color("Color5",
color(255, 255, 1, 255))
Centre = vec2(0,-0.4)
end
function draw()
background(40, 40, 50)
Gradient.mesh.shader.centre = Centre
Gradient.mesh.shader.aspect = vec2(GradientAspect, 1)
Gradient.mesh.shader.colors = {Color1, Color2, Color3, Color4, Color5}
Gradient.mesh.shader.step = {Step1, Step2, Step3, Step4, Step5}
Gradient.mesh:draw()
end
function touched(t)
Centre = vec2(-0.5 + t.x/ WIDTH , -0.5 + t.y/HEIGHT)
end
--# Gradient
Gradient = {}
function Gradient.setup()
Gradient.mesh = mesh()
Gradient.mesh:addRect(WIDTH/2, HEIGHT/2, WIDTH, HEIGHT)
Gradient.mesh.shader = shader(
[[
uniform mat4 modelViewProjection;
uniform lowp vec2 aspect; // set to (1,1) for circular gradient, (0,1) or (1,0) for linear, or fractional, eg (1, 0.5) for oval
attribute vec4 position;
attribute vec4 color;
attribute vec2 texCoord;
// varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
void main()
{
// vColor = color;
vTexCoord = (texCoord - vec2(0.5,0.5)) * aspect;
gl_Position = modelViewProjection * position;
}
]],
[[
precision highp float;
const int no = 5; //the number of gradation points you want to have
// uniform lowp sampler2D texture;
uniform lowp vec2 centre; // centre of gradient
uniform float step[no]; // transition points between colours, 0.0 - 1.0
uniform lowp vec4 colors[no]; // colours to grade between
//varying lowp vec4 vColor;
varying highp vec2 vTexCoord;
varying float vDistance;
void main()
{
float dist = distance( vTexCoord, centre);
lowp vec4 col = colors[0];
for (int i=1; i<no; ++i) {
col = mix(col, colors[i], smoothstep(step[i-1], step[i], dist));
}
gl_FragColor = col; //texture2D( texture, vTexCoord ) * col;
}
]]
)
end