<p>You don't need to render to texture to achieve an effect like this. Use <a href="https://open.gl/depthstencils" rel="nofollow noreferrer">stencil buffer</a>.</p>

<p>The visibility polygon can be drawn using <code>GL_TRIANGLE_FAN</code>, if you start from the middle:</p>

<p><a href="https://i.sstatic.net/R6FZS.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/R6FZS.png" alt="mask"></a></p>

<p>At the beginning of each frame:</p>

<ol>
<li>Clear the stencil buffer (and enable stencil test)</li>
<li>Set the stencil function to always pass, and to replace the current value in the buffer to a greater than zero number (for example one)</li>
<li>Draw the visible part as a <code>GL_TRIANGLE_FAN</code>. If you have multiple characters/lights, draw the visibility polygon for each.</li>
</ol>

<p>Now the stencil buffer contains 1 at visible locations and 0 where the character can't see.</p>

<p>Once you have a stencil buffer like this, you can control which objects you want to draw using glStencilFunc. Do not write to the stencil buffer, just use the stencil test to discard fragments which are visible/invisible.</p>

<p>If you want to draw a background which is visible everywhere, use <code>GL_ALWAYS</code>. For objects which are only displayed in the visible area use <code>GL_EQUAL</code> and <code>1</code>. Similarly you can draw something (for example a dark quad) just in the invisible parts of the scene with <code>GL_EQUAL</code> and <code>0</code>.</p>

<p>If it is not clear, how to use stencil buffers, check out <a href="https://open.gl/depthstencils" rel="nofollow noreferrer">this tutorial</a></p>

CC BY-SA 3.0
2017-08-30T07:50:13.947Z
Thanks! I had seen that along the way, but thought it was for something else. One question though, is a stencil buffer all or nothing, or would it be possible to have some parts be more/less visible based on ie: distance from light source, overlapping light sources.
AgentPaper
CC BY-SA 3.0
2017-08-30T09:00:48.577Z
The value (in case of a 8bit stencil) can be anything between 0-255. There are also glStencilOp's like `GL_INCR` and `GL_DECR`. If 0=hidden, 1=half-visible, 2=visible, then you can draw a black quad on the screen with `GL_EQUAL` and `0`, and a half-transparent gray quad with `GL_EQUAL` and `1`. If you would like to draw continuous shadow gradients, then you have to use a shadow texture. But stencil buffers are still really useful even if you have a shadow texture, because the stencil test is much cheaper than a discard in the fragment shader
Iter Ator
CC BY-SA 3.0
2017-08-31T00:27:05.500Z
Hm, so sounds like I definitely want a stencil buffer to mark off everything that's not lit up at all. However I would definitely like to be able to have gradient shadows or possibly even tinted shadows for various effects. So then I'd need a texture buffer for that? Or a frame buffer? Or are those the same thing?
AgentPaper
CC BY-SA 3.0
2017-08-31T09:10:01.070Z
If you render to texture, you will use a frame buffer with only one color attachment. A framebuffer is an object, which contains depth+stencil buffer and color attachment(s). You already use the default framebuffer to render to the screen. But if you would like to render offscreen (to a texture) you have to create a new one for it. The texture is the color attachment in that case. I advise you to implement it with stencil buffers only, and if everything looks as intended, start experimenting with textures
Iter Ator
CC BY-SA 3.0
2017-09-02T03:59:07.033Z
Manged to get the stencil version up and running, everything looks pretty good. Added checks for winding on the line segments so you can see the object casting the shadow as well, which makes for a nice effect. How do I tell OpenGL which frame buffer to draw to? Do I need a different shader program for that, or do I just use the same one like for stencil drawing? And for stencil drawing, would it be more efficient to use a specific program that doesn't take color data for that draw call, or does that not matter?
AgentPaper
CC BY-SA 3.0
2017-09-02T08:58:02.757Z
You don't have to change the shaders if you render to texture instead of "directly" to the screen. Just tell OpenGL before drawing that instead of the default framebuffer, use the one you created. Read a tutorial about rendering to textures, and If you have further questions about that, please open a new question.
Iter Ator
CC BY-SA 3.0
2017-08-30T07:12:36.397Z
2017-08-30T07:18:24.450Z
2017-08-30T07:18:24.450Z
Iter Ator
<p>I've been working on a 2d shadow system for a school project, using <a href="http://ncase.me/sight-and-light/" rel="nofollow noreferrer">this method</a> to generate visibility polygons. However, I'm having issues figuring out how to draw those visibility polygons in a way that reveals everything drawn within them, rather than drawing over them like a normal sprite would.</p>

<p>From what I've been able to figure out, it seems like what I want to do is to draw the visibility polygons to some texture first, and then use that texture somehow when drawing the rest of the objects on the screen to get the shadow/light effect.</p>

<p>Unfortunately all the tutorials I've been able to find aren't very helpful. So, my questions are:</p>

<p>1) How do I tell OpenGL to render to a texture instead of the screen?</p>

<p>2) How do I use that texture to create the effect I want?</p>

CC BY-SA 3.0
2017-08-31T17:49:49.197Z
this is somewhat the same [question or atleast the answer is the same as this](https://computergraphics.stackexchange.com/questions/1887/how-to-implement-a-realtime-2d-light-renderer-with-fog-colored-light-on-the-gpu). the approach is essentially the inverse of the answer you got. Apparently the examples have undergone link rot so i need to see if i can find an alternate solution for this.
joojaa
CC BY-SA 3.0
2017-09-01T18:22:14.967Z
With one lightsource they may be similar but that approach wouldn't work for multiple light sources, which is something I want to be able to do.
AgentPaper
CC BY-SA 3.0
2017-09-01T21:57:46.740Z
It would work with as many light sources as you like. Just render multiple times.
joojaa
<opengl><rendering><texture><shadow>
OpenGL: Rendering 2D shadows
AgentPaper
# OpenGL: Rendering 2D shadows

(Asked by: username_0 on 2017-08-30)

I've been working on a 2d shadow system for a school project, using [this method](http://ncase.me/sight-and-light/) to generate visibility polygons. However, I'm having issues figuring out how to draw those visibility polygons in a way that reveals everything drawn within them, rather than drawing over them like a normal sprite would.

From what I've been able to figure out, it seems like what I want to do is to draw the visibility polygons to some texture first, and then use that texture somehow when drawing the rest of the objects on the screen to get the shadow/light effect.

Unfortunately all the tutorials I've been able to find aren't very helpful. So, my questions are:

1) How do I tell OpenGL to render to a texture instead of the screen?

2) How do I use that texture to create the effect I want?

**Tags:** opengl, rendering, texture, shadow

> **Comments:**
> **username_1**: this is somewhat the same [question or atleast the answer is the same as this](https://computergraphics.stackexchange.com/questions/1887/how-to-implement-a-realtime-2d-light-renderer-with-fog-colored-light-on-the-gpu). the approach is essentially the inverse of the answer you got. Apparently the examples have undergone link rot so i need to see if i can find an alternate solution for this.  
> **username_0**: With one lightsource they may be similar but that approach wouldn't work for multiple light sources, which is something I want to be able to do.  
> **username_1**: It would work with as many light sources as you like. Just render multiple times.  

---

## 1 answers

### Answer by username_2 on 2017-08-30. Score: 3 | Accepted answer

You don't need to render to texture to achieve an effect like this. Use [stencil buffer](https://open.gl/depthstencils).

The visibility polygon can be drawn using `GL_TRIANGLE_FAN`, if you start from the middle:

[![mask](https://i.sstatic.net/R6FZS.png)](https://i.sstatic.net/R6FZS.png)

At the beginning of each frame:

1. Clear the stencil buffer (and enable stencil test)
2. Set the stencil function to always pass, and to replace the current value in the buffer to a greater than zero number (for example one)
3. Draw the visible part as a `GL_TRIANGLE_FAN`. If you have multiple characters/lights, draw the visibility polygon for each.

Now the stencil buffer contains 1 at visible locations and 0 where the character can't see.

Once you have a stencil buffer like this, you can control which objects you want to draw using glStencilFunc. Do not write to the stencil buffer, just use the stencil test to discard fragments which are visible/invisible.

If you want to draw a background which is visible everywhere, use `GL_ALWAYS`. For objects which are only displayed in the visible area use `GL_EQUAL` and `1`. Similarly you can draw something (for example a dark quad) just in the invisible parts of the scene with `GL_EQUAL` and `0`.

If it is not clear, how to use stencil buffers, check out [this tutorial](https://open.gl/depthstencils)

> **Comments:**
> **username_0**: Thanks! I had seen that along the way, but thought it was for something else. One question though, is a stencil buffer all or nothing, or would it be possible to have some parts be more/less visible based on ie: distance from light source, overlapping light sources.  
> **username_2**: The value (in case of a 8bit stencil) can be anything between 0-255. There are also glStencilOp's like `GL_INCR` and `GL_DECR`. If 0=hidden, 1=half-visible, 2=visible, then you can draw a black quad on the screen with `GL_EQUAL` and `0`, and a half-transparent gray quad with `GL_EQUAL` and `1`. If you would like to draw continuous shadow gradients, then you have to use a shadow texture. But stencil buffers are still really useful even if you have a shadow texture, because the stencil test is much cheaper than a discard in the fragment shader  
> **username_0**: Hm, so sounds like I definitely want a stencil buffer to mark off everything that's not lit up at all. However I would definitely like to be able to have gradient shadows or possibly even tinted shadows for various effects. So then I'd need a texture buffer for that? Or a frame buffer? Or are those the same thing?  
> **username_2**: If you render to texture, you will use a frame buffer with only one color attachment. A framebuffer is an object, which contains depth+stencil buffer and color attachment(s). You already use the default framebuffer to render to the screen. But if you would like to render offscreen (to a texture) you have to create a new one for it. The texture is the color attachment in that case. I advise you to implement it with stencil buffers only, and if everything looks as intended, start experimenting with textures  
> **username_0**: Manged to get the stencil version up and running, everything looks pretty good. Added checks for winding on the line segments so you can see the object casting the shadow as well, which makes for a nice effect. How do I tell OpenGL which frame buffer to draw to? Do I need a different shader program for that, or do I just use the same one like for stencil drawing? And for stencil drawing, would it be more efficient to use a specific program that doesn't take color data for that draw call, or does that not matter?  
> **username_2**: You don't have to change the shaders if you render to texture instead of "directly" to the screen. Just tell OpenGL before drawing that instead of the default framebuffer, use the one you created. Read a tutorial about rendering to textures, and If you have further questions about that, please open a new question.  

---

