The effect I'm looking for is to have a single large background image that is always visible (at full alpha) and then show a second image (what I call a light map or specular map) that is partially shown over the top based on a third image (which is effectively a mask).

The effect is similar to this effect except instead of simply darkening or lightening the background image using the third image it needs to mask the second without effecting the first at all.

The third image is the only one that moves therefore hard baking the third images alpha into the second image isn't an option.

If my explanation isn't clear I'll provide visual examples when I have more time.

I'd prefer not to go down a shader route as I haven't taught myself this area yet so unless I have too I'd rather try to achieve this with simple alpha blending. Happy to use a shader approach.



These third images are obviously light sources being cast onto the first image showing the specular information from the second image to simulate the light 'shining' off the objects in the first image. The solution I implement will need to allow two light sources to potentially overlap so my current thoughts are that the alpha values of the two images will need to be combined (Added?) to produce a final image which masks the second image?

Don't worry about things like coloured lights. For this technique the lights are all considered white.

  • 6
    \$\begingroup\$ Since OpenGL 3 and OpenGL ES2 everything is done with shaders. So you have to learn shaders anyway... and it is much easier to make stuff with shaders than without them :) \$\endgroup\$
    – kravemir
    Commented Jun 12, 2013 at 10:31
  • \$\begingroup\$ If I understand correctly you have one fixed background. Few moving objects that reveals parts of another fixed image at areas that are overlapped by them (with mask). \$\endgroup\$
    – kravemir
    Commented Jun 12, 2013 at 10:34
  • \$\begingroup\$ Seems like you have the gist of it yes Miro. Are you saying there is no other way? Thanks. \$\endgroup\$ Commented Jun 12, 2013 at 11:01
  • \$\begingroup\$ @Miro If it is indeed easier, could you provide an answer which roughly outlines the steps? Thanks. \$\endgroup\$ Commented Jun 12, 2013 at 13:13
  • \$\begingroup\$ @Miro I'm not finding any documentation that states you have to use shaders in OpenGL 3/ES2. Could you please provide links to the information? Thanks. \$\endgroup\$ Commented Jun 17, 2013 at 7:37

1 Answer 1


For fixed-function, this might be what you want:


Essentially, use the blend modes (and proper use of the color channels vs alpha channel) to write a mask into your backbuffer and then render a foreground image masked.

With shaders, you can simply provide the mask/light texture as an input to the fragment shader, query the "real" input textures (for sprites or whatnot) and the mask texture and then discard fragments or blend them appropriately.

It's been long enough since I've used GLSL that the following code is probably syntactically invalid and certainly idiomatically off, but the gist of it is:

// mask.fragment.glsl
layout(location=0) uniform sampler2D sMask;
layout(location=1) uniform sampler2D sSprite;

in vec2 aTexCoord;
in vec4 aColor;

layout(location=0) out vec4 rtColor;

void main() {
  vec4 mask = texture2D(sMask, gl_FragCoord.xy);
  vec4 sprite = texture2D(sSprite, aTexCoord);
  rtColor = mask * sprite * aColor;

You can change up how you use mask to make it color-based, alpha-based, whatever. Using that snippet you would use the alpha channel of the mask texture to make hide details and the color to have the light change the output color, supporting colored lighting.

  • \$\begingroup\$ Thanks @Sean Middleditch, I had tried the solution in the answer you linked to previously but I then read that glBlendFuncSeparate() wasn't available in some of the more modern versions of OpenGL (3 & ES2) is that correct? If so is there a way to do the fixed function approach without this call? If that's too much hassle I'll try and knock up a shader approach as you've outlined here. Thanks! \$\endgroup\$ Commented Jun 18, 2013 at 8:00
  • \$\begingroup\$ Also, that link outlines almost exactly what I'm trying to achieve. \$\endgroup\$ Commented Jun 18, 2013 at 8:04
  • 3
    \$\begingroup\$ glBlendFuncSeparate() is still available (and not deprecated as far as I can see) in all current OpenGL flavours. \$\endgroup\$
    – GuyRT
    Commented Jun 18, 2013 at 10:22
  • \$\begingroup\$ +1ed already, but I noticed a couple of things in the glsl. Don't you need a different uniform location for "sSprite"? Did you mean to write "mask.a" in the last line (since you say in the text "use the alpha channel...")? \$\endgroup\$
    – GuyRT
    Commented Jun 18, 2013 at 10:27
  • \$\begingroup\$ @GuyRT: typo for location fixed. I'm using all of mask since that way you get multiplicative blending for any color in the mask and you use alpha to make it mask off pixels, useful if you want to colorize your light mask. Make the mask color all white to have no color changes. If you don't want colorization, just use a one-component texture instead. \$\endgroup\$ Commented Jun 18, 2013 at 17:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .