1
\$\begingroup\$

I'm trying to achieve an effect like in the image bellow. Basically I will have a 2D texture and I want a small area around a point (let's call it "light source") to be slightly better lit (i.e. be brighter). The light source will never move from its original position nor will it seem to "pulse" like the light of a fire for example. All the other areas further away will have some default brightness.

From my understanding, this can be done using a light map, but I was wondering whether it was possible to come up with a formula in the fragment shader of the texture below that changed the brightness of my pixels so that it is very bright around a particular point and quickly faded to a default value for the pixels further away. I tried working with something like this:

precision mediump float;
uniform sampler2D u_Texture;  

uniform vec3 u_LightPosition; 
varying vec3 v_Position;
varying vec2 v_TexCoordinate;

void main() {
    float dist = length(v_Position - u_LightPosition);
    gl_FragColor = (1.0 / (c + b * dist + a * dist * dist) + 0.15) * texture2D(u_Texture, v_TexCoordinate); 
}

where c, b and a are hardcoded and adjusted by myself. However I wasn't able to find any combination of c, b and a that achieved an effect like the one from the image, because the brightness doesn't fade away quickly enough and it's very gradual. I think that's expected behaviour from a quadratic expression anyway, so my approach is clearly wrong and it's not a matter of adjusting c, b and a. What should I try then?

enter image description here

\$\endgroup\$
  • \$\begingroup\$ @Mokosha I think I already covered those questions. \$\endgroup\$ – async May 18 '14 at 14:57
1
\$\begingroup\$

I think the easiest/fastest solution for this would indeed be a lightmap.

  • Create a second texture, big enough to fit the whole screen.
  • Clear it to black and render your lights into it using their actual color.
  • Bonus: If you've got a wall or similar that should be in front of a light map, just draw it using black onto the lightmap.
  • Once you're done with your scene, render the lightmap ontop your screen using multiplicative blending (so bright white in the light map means fully illuminated; bright red would mean a red light, etc.).

If you still prefer the shader approach, there are other functions you can use rather than a quadratic equation.

For example, you could try 1 - x4 multiplicative with your initial fragment color, but only if the distance is between "full brightness distance" and "full darkness distance".

\$\endgroup\$
  • \$\begingroup\$ My light will be white, so I think you're suggesting creating an image like this (mdeverdelhan.developpez.com/tutoriel/dynamiclight/tutoriel2/…) and then blending it with the original texture? Obviously the black areas should be some sort of grey, since I still want those areas to be visible, but darker. \$\endgroup\$ – async May 18 '14 at 14:59
  • \$\begingroup\$ Yes, exactly. Black will stay black, gray will become dim "backgrounds", etc. You can also use lower resolution textures if you want more performance. Like one fourth of your screen size should be fine if you blur your stuff anyway. \$\endgroup\$ – Mario May 19 '14 at 8:15
  • \$\begingroup\$ Thanks, I will try it later today or this week. One more thing: does this require an extra frame buffer? It seems so from your wording. I'm concerned about the speed of this approach then. \$\endgroup\$ – async May 19 '14 at 9:01
  • \$\begingroup\$ Not exactly. You'll need one render-to-texture pass to render your lights on a texture, but you're able to cache that as well (unless things change). Doing it solely in your shaders might be faster depending on your target hardware (and also the number of lights to consider per pixel). On hardware with poor shader support/performance (like older Intel onboard-GPUs) the texture approach should be faster IMO. \$\endgroup\$ – Mario May 19 '14 at 11:13

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.