# How do 2D volumetric lights work?

Context

So in my current project (written in Java using LWJGL / OpenGL, so GLSL for shaders) I added lighting quite a few months ago, which was already an interesting challenge, having never done something like that before. Now I did my research, and in the past few days I found absolutely nothing particularly helpful about this subject (which was really surprising, I thought this to be a much more common problem), which is why I am asking here. Anyway, after a lot of searching around and asking for help, this is what the current lighting system looks like:

Desired effect

The current lighting is somewhat neat but not good enough, as I would like it to have an additional parameter for something like light width (currently there are already color, intensity, angle, smoothness and linear + quadratic attenuation parameters).

What I would like to achieve is an effect along the lines of this (paint.net mockup, but should make it clearer):

It sounds like such a simple thing to do and yet I can't get my head around how to do it (I thought about somehow having two different light positions and tracing lines between that or rotating the current fragment point in the fragment shader, but both seem incredibly slow and I don't even know where to start with them).

Edit

Here as requested the part of the fragment shader that's responsible for lighting:

for (int i = 0; i < numLights && i < MAX_LIGHTS; i++)
{
if (lightColor[i].a > 0.0 && myDepth >= minAffectedDepth[i] && myDepth <= maxAffectedDepth[i])
{
if (isSpotLight[i])
{
lightDistance = lightPosition[i] - myPos;
distance = length(lightDistance);
spotEffect = dot(normalize(spotDirection[i]), normalize(-lightDistance));

if (spotEffect > spotCosCutOff[i])
{
spotEffect -= spotCosCutOff[i];
spotEffect /= (1.0 - spotCosCutOff[i]);

spotEffect = pow(spotEffect, spotExponent[i]);
attenuation = spotEffect / (1.0 + linearAttenuation[i] * distance + quadraticAttenuation[i] * distance * distance);

color += attenuation * lightColor[i] * ownColor * lightColor[i].a;
}
}
else
{
color += ownColor * lightColor[i] * lightColor[i].a;
}
}
}


TLDR; I want to add "volumetric" lighting to my 2D project with GLSL, so a width parameter to the lighting system, which currently consists of punctual light sources (and for some reason, light sources in real life usually aren't perfectly punctual ;)).

• The last time I saw lights that worked like this, it was in a 3D modeling stuidio (3D Max?). I've never seen them anywhere else. A little searching shows that OpenGL does not have them, but this fellow managed an approximation. Maybe that will help you. Post is old enough that the demo images are missing, however. Dec 22, 2015 at 16:51
• @Draco18s Alright, thanks for the reply. I find it kind of hard to believe that there are no lights like this at all - not every single light in every 2D game every can be punctual right? That link is great, looks like the fellow uses a similar approach to the one I proposed; intersecting with a light "line", as far as I understand that is. Dec 22, 2015 at 17:20
• Could you show us the code that draws these lights? Dec 22, 2015 at 17:23
• @Peethor Oh yeah of course, forgot about that sorry - included it now :) Dec 22, 2015 at 17:49
• The term to look for in 3D is "area lights" (as in, light emanating from an area rather than a point). For real-time uses, these are often simulated as a sphere for "point" lights or a disc for directional lights. There are also techniques that can utilize constrained planes; the 3D equivalent of what you're looking for, I think. Unfortunately, I know very little about these other than their existence so I can't really provide a decent answer to your question. Dec 22, 2015 at 18:35