Skip to content

Instantly share code, notes, and snippets.

@ruuda
Last active December 19, 2019 00:23
Show Gist options
  • Save ruuda/1e212e049598e28451ebc2132539f4ae to your computer and use it in GitHub Desktop.
Save ruuda/1e212e049598e28451ebc2132539f4ae to your computer and use it in GitHub Desktop.
LED wall shader
// Simulates n colored point lights (LEDs) shining at a wall from a distance wd.
// Wall distance; increase for more fuzzy lights,
// decrease for sharper point lights.
float wd = 0.15f;
const int nLights = 4;
const vec3 lights[nLights] = vec3[](
vec3(1.0f, 0.0f, 0.0f),
vec3(0.0f, 1.0f, 0.0f),
vec3(0.0f, 0.0f, 1.0f),
vec3(1.0f, 0.0f, 0.0f)
);
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
vec2 uv = fragCoord.xy / iResolution.xy;
// Correct screen aspect ratio while keeping lights centered.
uv.y = (uv.y - 0.5f) * iResolution.y / iResolution.x + 0.5f;
fragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
for (int i = 0; i < nLights; i++) {
// Compute the falloff (power falls off as r², plus a diffuse wall
// that contributes a dot(dl, normal) / dl factor, but normalize
// such that the power does not depend on wd.
vec2 lightPos = vec2(float(i + 1) / float(nLights + 1), 0.5f);
vec2 dl = lightPos - uv;
float falloff = (wd * wd) / (dl.x * dl.x + dl.y * dl.y + wd * wd);
fragColor.xyz += lights[i] * falloff;
}
// Reduce clipping artifacts at the cost of reduced maximum brightness
// and non-linear color interpolation.
fragColor.xyz = log(fragColor.xyz + 1.0f);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment