4
\$\begingroup\$

I have some point lights in my game which are just sprites implemented with help of HLSL. Currently I'm trying to implement dynamic shadows and I managed to make the program calculate the area in which the light should be drawn (area that is not behind walls etc).

Here is what it looks like when I draw a line strip between the calculated points:

enter image description here

So I was wondering how I would draw the light sprite only inside that line strip? For example if a pixel is inside that area, then draw it, etc. Can it be done with HLSL (I'm not that good at HLSL), or perhaps I should just do it in XNA?

\$\endgroup\$
  • \$\begingroup\$ The naive way would be to perform a point/bounding test and use the HLSL clip intrinsic. However, it's a concave bounding volume, and will probably cause you more headaches than you want to deal with when doing shadow volumes. \$\endgroup\$ – Jovan Jul 31 '13 at 15:36
  • \$\begingroup\$ catalinzima.com/samples/dynamic-2d-shadows \$\endgroup\$ – ClassicThunder Jul 31 '13 at 15:58
  • \$\begingroup\$ @ClassicThunder - Catalin references the GDnet article but the URL 404s - check out my answer below for a working link. \$\endgroup\$ – Jovan Jul 31 '13 at 16:06
  • 1
    \$\begingroup\$ As for alternatives, I always like: redblobgames.com/articles/visibility \$\endgroup\$ – MichaelHouse Jul 31 '13 at 16:16
2
\$\begingroup\$

If you want to block out the parts of that sprite that should be shadowed, there is an alternative approach to doing this that uses simpler geometry and doesn't require a lot of shader manipulation.

  1. Calculate the shadow volumes themselves. This is a fairly common practice and there is lots written up about it. Check out this GameDev article for some information.
  2. Render these shadow volumes to the stencil buffer, providing us with a mask of where we won't render the point light sprite.
  3. Render the point light sprite but disqualify the fragments that are inside of the stencil buffer.

MSDN XNA documentation has an introductory article to using the stencil buffer for this operation.

Corollary: when doing any sort of graphics programming (and dealing with shadows especially), its helpful to think in both terms of what can be seen and what can't be seen. It comes up a lot that one is far easier to work with in certain situations than the other.

\$\endgroup\$
  • \$\begingroup\$ So instead I need to calculate the area where there is no light, as opposed to where there is light (like I have it now)? Is it not possible to render the area where the light should be to the stencil buffer and then draw parts of the sprite which are inside that area? \$\endgroup\$ – radioprotector Jul 31 '13 at 20:05
  • 1
    \$\begingroup\$ It's possible, but more difficult and doesn't scale as well. Plus, you have a concave bounding volume, which isn't all that friendly. To make it possible, you need to take the custom shape that you made and triangulate it so that it has a surface. The lines by themselves do not have a concept of what's inside and what's outside, and that's where the issue is - you would need to find a way to answer the question "for a point P, is it inside or outside of this custom shape?". I recommend you don't do this. Render each piece of shadow geometry instead, and by overlap you'll get the right shape. \$\endgroup\$ – Jovan Jul 31 '13 at 20:45

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.