2
\$\begingroup\$

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:

Current lighting system

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):

Desired lighting effect

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 ;)).

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Draco18s Dec 22 '15 at 16:51
  • \$\begingroup\$ @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. \$\endgroup\$ – flotothemoon Dec 22 '15 at 17:20
  • \$\begingroup\$ Could you show us the code that draws these lights? \$\endgroup\$ – Peethor Dec 22 '15 at 17:23
  • \$\begingroup\$ @Peethor Oh yeah of course, forgot about that sorry - included it now :) \$\endgroup\$ – flotothemoon Dec 22 '15 at 17:49
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ – Sean Middleditch Dec 22 '15 at 18:35
1
\$\begingroup\$

I found a paper from Epic Games on how they do their area lights - relevant info starting on page 16. Essentially, you find the shortest distance to the line segment that defines your light source, and use that as the source of a light - in their case, a point light, but you could easily use your spotlight instead. They also use a calculation for the radiance of that point light so as to conserve energy for their PBR calculations, but if you're not using PBR then you probably don't need that.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.