How to do an illuminated spotlight effect

Hey all! I’m creating a program where I’d like to create a ‘spotlight’-like effect. I want to render all my graphic elements, but have it sort of darkened. Then around the mouse there should be an ellipse where the graphics are shown with full brightness. Ideally this would enable the user to “search” around the canvas. How would you do such a thing?

Something visually similar to this:
The problem with the code is just that depends calculating distance from each pixel to a location. I’d like to have multiple users and the resolution is 7800 x 2200, so there has to be a more efficient way of doing it.

Best regards,

whether it is a 2D scene you can try this addons:

if you draw all your graphics in to an ofFbo, with 50% alpha.
draw this fbo on to a black background
use subsection fbo example to draw part of the same fbo with higher alpha

maybe that works?

I recently wrote a simple fragment shader to create a spotlight effect on a texture per mouse position.
Feel free to reuse it:


  • the uniform value u_vFlip will flip the result upside down if set to 1 (default), which may be necessary depending on how you grab the texture (like if you’re using ofFbo). You can set that to 0 to prevent flipping.

  • the shader also desaturates the darkened part of the texture, and adds brightness to the spotlight area - you can comment out lines 71 and 86 to prevent that

  • in the calls to the circle() function, like line 74: float dimPct = circle(st, u_mouse, 250., 70.); the 3rd argument is the size (in pixels) of the spotlight and the 4th argument is the smoothness of the transition from light to dark. Set the 4th argument to 0 for a hard edge spotlight

  • the dimming actually happens twice to get a large spotlight multiplied by a smaller spotlight.
    in this code starting line 73, you can play with the .7 and/or .4 values to get a darker/lighter dimming effect
    0 would be full black

float dimPct = circle(st, u_mouse, 250., 70.);
float dimPctSpot = circle(st, u_mouse, 150., 80.);
float dark = map(dimPctSpot, .0,1., .7,1.) * map(dimPct, .0,1., .4,1.);

1 Like

Thanks for all the replies, I’ll look into it!