2D soft shadows

Hi!

I’m in the process of creating the light engine for my LibGdx project. I’m using box2d’s raycasting to build a light mesh (it is show on the picture).

http://s12.postimg.org/c63r2b7m5/help.jpg

With this method though I can only create hard shadows and I don’t have any idea how I could make the shadow edges smooth or “realistic” looking.
I was hoping that s’one will be able to shed some light on my issue.

There’s an aging gamedev.net article on drawing shadow penumbrae with textured “fins” here. This seems like it might be readily applicable to the method you’re using right now.

Another approach relies on shaders to generate a soft shadow texture; it’s more complicated, but lets you use arbitrary sprites to cast shadows. You can read about it here.

The library box2dlights achieves this by rendering the light meshes into a framebuffer that’s lower resolution than the screen resolution.
Then it blurs the framebuffer using gaussian blur and renders that to the screen.
For reference: https://github.com/libgdx/box2dlights

I managed to implement the penumbra’s outline as shown on this picture.

http://s21.postimg.org/kwfmlz393/asd.jpg

I have a penumbra texture but my problem is I don’t know how to texture the ABC triangle with it.
Could anyone explain how should I do it?

The penumbra texture:

[quote]You can clearly see how the shadow fin will be rooted at the bottom left, and the two edges running vertical and diagonally to the top edge. Also note the line of white pixels along the right side, this prevents blending artefacts along the vertical edge. The bottom right half of the texture is unused, although if you really wanted to you could pack something else in here just as long as you’re careful not to bleed over the edge.
[/quote]
It sounds like A goes in the bottom-left corner, B the top-right, C the top-left.

It sounds like A goes in the bottom-left corner, B the top-right, C the top-left.
[/quote]
So when I’m creating the triangle’s mesh and sending the texture coordinates per vertex, I’d have to set A(0,0), B(1,1) and C(0,1) then use these coords in the fragment shader to get the appropriate color of the penumbra texture?

Should be right, don’t hesitate - just do it! :smiley:

[EDIT]

I’d still like to get a little help with the blending modes.
Right now I’ve managed to get everything working apart from that.

Here is a pic of the problem:

I should mention that I’m implementing deferred rendering since I’m going to use normal mapping later on.

At the moment here is how I’m rednering my scene:

  • I’m drawing every diffuse texture into an FBO
  • Then I’m binding the FBO’s texture and drawing it with ambient lighting to the default FBO
  • Then drawing the light’s meshes one by one using additive blending and binding the diffuse FBO’s texture
  • Then drawing the penumbras (not sure what blending mode to use here or how to set it up)

To be honest I’m not sure that this rendering method is correct at all.
Could s’one tell me how to set up the the penumbra drawing or if my method of rendering is good at all?
Thanks in advance! :slight_smile:

I really don’t like bumping my own thread, but I’m kind of desperate for an answer since I’m stuck with this. :frowning:

I can’t give you tested code, but you want a simple multiplication of the fin texture and the FBO, so according to https://www.opengl.org/wiki/Blending#Blend_Equations, you want something like:


glBlendFunc(GL_DST_COLOR, GL_ZERO)

One thing to note is that this is alpha blending. With that image given, you need to turn all white into alpha. This will allow the alpha blending to work. I know a lot of people who can’t get glBlendFunc(GL__DST_COLOR, GL_ZERO); to work. Try glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); That is all in the GL11 package.

Happy coding!

For his usecase he needs color modulation and not alpha blending, since he is trying to darken existing pixels.

Exclude penumbras from lights geometry and then just render them as additive. All lighting is additive and penumbra areas are just partially shadowed lights. No need to make this any harder. If you render multiple lights to single buffer you can’t solve this problem with blending anymore.

I’m already doing that somewhat. Since my light’s geometry is built with a triangle fan I can’t exclude all of it.

The cyan lines on the picture are the light’s geometry and the red triangles are the shadow fins.
Half of the soft shadow is looking fine but the problem is the white triangle areas. Thats where part of the shadow fin meets with part of the light so they (I guess) amplify eachother and that’s what I can’t solve at the moment.

Hmm, I can think of 3 possible solutions here:

  • take an incorrect shortcut and move the whole penumbra into the half not covered by the triangle strip, squishing the soft shadow into half the width (you could make up for this with some texture editing)
  • move to a buffer per light and do the multiplication blend
  • bite the bullet and fix your light geometry triangle fan: you could just add an edge from the light source to the far corner of the shadow fin and move the end-point of the neighbouring triangle to the corner of the occluder

Just fix that geometry. With modern GPU triangle strips don’t usually offer any performance benefits sometimes they can even make things worse. Just always use indexed triangles and life is easier.