With Stencyl 4.0, shader arrays are supported which allows for more options for shaders including this multiple lights shader.
https://gfycat.com/ParallelColdFunnelweaverspiderIt's similar to the circle light shader but modified to support multiple lights. Some properties have been changed to use list attributes rather than number attributes. After modifying the lists, set the shader properties to the lists to update the shader. The array size is set at 100 for performance reasons but you can edit the shader code to change that if you need to.
In addition to this shader, I've also checked my other shaders and updated those as needed so they work without errors on both desktop and HTML5.
Here are the properties of the shader that you can set:
enabled (bool) -- This is used to control whether most of the shader code is run. It's useful if you want to disable the shader without needing to reapply shaders. If not using the custom block it defaults to false so you'll need to set it to true first.
centerX (float array) -- This is the X center of the light circle.
centerY (float array) -- This is the Y center of the light circle.
minDarkAmount (float) -- This is how dark the screen becomes just outside of the light radius (range: 0-1)
maxDarkAmount (float) -- This is the maximum darkness of the screen and is reached at the dark radius (range: 0-1)
lightRadius (float) -- This is the inner radius of the light that has no darkness at all.
darkRadius (float) -- This is the outer radius of the light at which point the max darkness is reached.
red (float array) -- This is the red value of the light (range: 0-1)
green (float array) -- This is the green value of the light (range: 0-1)
blue (float array) -- This is the blue value of the light (range: 0-1)
Stencyl Code#ifdef GL_ES
precision mediump float;
#endif
varying vec2 vTexCoord;
uniform vec2 uResolution;
uniform vec2 uResolutionUs;
uniform sampler2D uImage0;
uniform bool enabled;
uniform float centerX[100];
uniform float centerY[100];
uniform float minDarkAmount;
uniform float maxDarkAmount;
uniform float lightRadius;
uniform float darkRadius;
uniform float red[100];
uniform float green[100];
uniform float blue[100];
void main()
{
vec2 uv = vTexCoord;
vec4 tex = texture2D(uImage0, uv);
if (!enabled)
{
gl_FragColor = tex;
return;
}
float lightAmount = (1.0 - maxDarkAmount);
vec4 tex2 = vec4(lightAmount, lightAmount, lightAmount, 1.0);
vec2 res = uResolution.xy;
float scale = res.x / uResolutionUs.x;
float darkRange = maxDarkAmount - minDarkAmount;
float lightRad = lightRadius * scale;
float darkRad = darkRadius * scale;
for (int i = 0; i < 100; i++)
{
float xDiff = ((centerX[i] / uResolutionUs.x) - uv.x) * res.x;
float yDiff = ((1.0 - (centerY[i] / uResolutionUs.y)) - uv.y) * res.y;
float dist = sqrt((xDiff * xDiff) + (yDiff * yDiff));
float darkAmount = minDarkAmount + min(darkRange * ((dist - lightRad) / (darkRad - lightRad)), darkRange);
vec3 colorMod = vec3(red[i], green[i], blue[i]);
if (dist < lightRad)
{
tex2 = 1.0 - ((1.0 - tex2) * (1.0 - vec4(colorMod, 1.0)));
}
else if (dist < darkRad)
{
tex2 = 1.0 - ((1.0 - tex2) * (1.0 - vec4(colorMod * (1.0 - darkAmount), 1.0)));
}
}
gl_FragColor = tex * tex2;
}