April Sample Online!

I finally finished the April sample. I know it’s May already but the MVP Summit and the Easter Holiday took most of this month :)

So for April we have Dynamic 2D Shadows. Check it out in the Samples section, and let me know what you think. Or download it directly, here.

I hope you will enjoy this sample.

DynamicShadows3

Categorized: XNA
  • http://www.ziggyware.com Ziggy

    Awesome sample Catalin!

  • http://nick.gravelyn.com Nick

    Excellent stuff! I’ll probably use that for Castle to get some cool lighting.

  • http://www.cdx-games.com Cdxrd

    Love this sample, looked through the code, got lost a few times, but it should be easier to follow when i can look at it in something other than notepad. I see a lot of stuff in here I’ve never touched before, like the vertex’s and half the calls to spritebatch.. I would love to see a full blown tutorial done out of this.. =) Otherwise, awesome..will have to play and see how i can use it.. maybe i can start another project I will get 90% done and drop.. =) hehe

  • http://www.catalinzima.com Catalin Zima

    Go ahead and use it Nick. If you find any performance improvement tricks (shouldn’t be too hard, since I focused on getting it done first; didn’t care much about perf)

    Cdxrd: Glad you liked it. There aren’t really too many complex things in there. Reading the original article on Gamedev is a must, because it explains the theory behind these shadows very well (even though it has some OpenGl/C++ code in it). The calls to spritebatch are just overrides of the normal ones, with some added parameters.

    Some points of confusion might come from the several ways in which I use alpha blending. CornflowerBlue has a series of 3 articles that explain the alpha blending stuff. http://blogs.msdn.com/etayrien/archive/2006/12/19/alpha-blending-part-3.aspx

    A full blown tutorial is not likely right now, since the exam session is approaching :) But if I get enough requests, I’ll try to fit it in my schedule.

  • Deimos

    Great sample! That is exactly what I was looking for to improve the graphics of my 2d game. But the (bad) performance still remains a serious problem for me. In my game, the (scrolling)levels are much bigger as the one in the sample. Furthermore i also would like to add some more lights. I tried this within the sample and the result was like a slideshow 😉

    I experienced that the most performance loss comes while drawing the shadowvertices (last lines of the DrawShadows method). Maybe merging all convexhulls shadows to one single buffer could help here. Also precalc the shadowvertices on specific events (eg. on new light, on new convexhull, on lightposition change, on convexhullposition change, on scaling light range…) instead of doing this each frame. Therefor an illumination manager class, which holds shadowvertices and manages all convexhulls and lightsources, could be helpfull. …Just my thoughts.

    Any further ideas?

  • http://www.catalinzima.com Catalin Zima

    It’s not drawing them that’s slow, it generating them
    A few ways to improve performance would be:

    * precompute shadows for static lights and objects

    * only compute/render shadows from lights that might be visible on the screen (for big scrolling levels) Note that some ofscreen objects/light will need to be included in the algorithm to make it work well

    * for each light, only cast shadows from objects which are in the light’s range

    * any optimization that you would do in a physics engine, to avoid testing for collision between two objects, you can do in the shadows sample, to avoid computing shadows for some light/object pairs

    There are probably a few other ways to increase performance, but the purpose of the article was to describe the technique :)

  • Soul

    Damn, this is awesome.. Finally something for us, who create 2D games :) Sadly I don’t understand much of it, but I sure try to put it to good use anyway. If you ever get time to make a tutorial out of this, that would be great!

    – Soul

  • http://www.catalinzima.com Catalin Zima

    Soul, you are the second person asking for a tutorial :)

    If I had more time, I would be glad to do it. Maybe after my exams are all done and passed, I’ll try to put together a tutorial explaining everything, but I can’t promise anything.

  • tuomas

    Great work Catalin! I’m trying to implement this in a game project that uses flatredball engine. I was wondering if you’re familiar with it and got any architectural ideas in how to integrate it with the engine? I might have to chop all the drawing in pieces and a tutorial on what’s going on with that math would be greatly appreciated.

  • http://www.catalinzima.com Catalin Zima

    I looked over the flatredball engine for a while, but not too much. So I’m afraid I can’t help you with integration.

  • Anton

    First of all forgive me for bad English, I from Ukraine.
    I started to learn XNA recently together with C #, therefore many things for me remain not clear. I hope you will help me to solve my problem. The matter is that I want render objects without shadow on it. I.e.only light gradient must be on objects, and shadow must be rendered on background.
    How it is possible to make it?
    If i draw objects and light texture on top of rendered scene(shadows and objects) it’s ends up with great performance hit…

    P.S. This (http://img237.imageshack.us/my.php?image=shadowsxp7.jpg) picture describe my case.

    In advance thanks.

  • http://www.catalinzima.com Catalin Zima

    I’ll look into it later today and tomorrow, and I’ll let you know.

  • SiliconMind

    Hey,
    first of all – great job! After i’ve finally managed to understand your code (after reading some gamedev.net and others) things are really getting into their places in my head :) This is great material for a full blown tutorial on 2D shadows. I hope you’ll find some time to write it in the future.

    The thing that makes me wonder is the optimization of your code. I’m a total noob when it comes to the XNA (although I’d written zillions lines of WinForms code) I wonder if there is a way to get done the heavy lifting by the shaders? I mainly refer to the ConvexHull.DrawShadows(…) method. Mike on his msdn blog draws his 2D shadows using shaders http://blogs.msdn.com/manders/archive/2007/03/14/shadows-in-2d.aspx although for now I can’t make much of his article :(

    As I wrote I’m totally new to the XNA and shaders thing, but it seems like this can be done. Maybe you could spare a few words on this? This would make your code sample completely awesome and maybe we all could learn from it something valuable 😉

  • http://www.catalinzima.com Catalin Zima

    Yes, I’m aware of Manders’ technique. I though hard about doing all those computations on the GPU myself, but there is a big difference between our samples.
    He only has lines for which to draw shadows, while I have polygons with arbitrary number of edges. For a line, no matter of the light’s position relative to it, the shadow always has the same shape. This is not so for a polygon, and depends both on the shape of the polygon and on the position of the light.

    One way to do this would be to draw the shadow volumes for each edge of the polygon, in the same way as Manders draws shadows for his lines, but depending on the level of detail of that polygon, this could result in a great number of Draw calls (order of tens), as opposed to a single Draw call for the whole object’s shadow, as it happens now. These add up, and may actually hurt performance more than benefit it.

    This is one area where DirectX10 geometry shaders would come in handy, as they could be used to generate the shadow’s geometry on the GPU, for any convex shape imaginable. But since XNA is DX9 only, for now I’ll have to stick to doing all this on the CPU.

    One other idea would be to move these computations on another thread, and use multi-threading, but this is dangerous territory as well.

  • SiliconMind

    Catalin, you are probably right, but since Xbox360 is a DX9 device, waiting for DX10 in XNA would be not much of solution for me :/

    But, what if we compute a line that stretches across a polygon that is supposed to cast shadow. This line would connect the two most outer points of that polygon, the ones that are on the edges of your shadow. Then we could use that line for calculating shadow using Manders method. Off course such a shadow would partially cover the shadow casting object itself, but then we could draw that object on top of the shadow layer or maybe use a pixel shader to “remove” parts of a shadow that “intersect” with the shadow casting object itself.

    Again this is only a rough idea, based on my “common sense logic” and not a deep knowledge of the XNA and shaders. The knowledge which i unfortunately don’t posses (yet) 😉

  • http://www.catalinzima.com Catalin Zima

    Yes. That’s the best idea I could also come up with :) I just forgot about it until you reminded me.

    I decided not to use it in the sample, because I though the extra tinkering needed to remove the artifacts might confuse some people.

    But mainly, that’s the way I would go about it, if I were to modify the sample.

  • SiliconMind

    Good to know that my “common sense logic” is not that bad after all 😀
    Unfortunately there is lots of (and i mean really) lots of work before me until I’ll be able to do it myself. Anyway, could you please share your thoughts and say which way would you go? Would you draw a shadow casting object on top of a shadow itself or would you use a pixel shader to “remove” portions of a shadow that cover the shadow casting object? Or maybe some other way? Any clues?

  • http://www.catalinzima.com Catalin Zima

    To be honest, I’m not really sure. Drawing the object on top of the shadow is not such a good idea, because it may cause shadowed objects to actually be drawn (like object lying in the shadow of other objects, and so on)

    What would probably be best on the long run is the idea to also assign a “height” when first processing the shadows, and when drawing the objects, only apply shadows on objects lower than this height. And an object is set to be a little higher than its own shadow. This would probably lead to the best result, where small objects don’t case shadows on objects larger than them. But it would also mean rewriting the way shadows are combined with the scene, adding a bit more shader complexity.

  • SiliconMind

    You are probably right. The moment I’d clicked “Post Comment” I’ve realized that when drawing objects on top of a shadow would cause serious problems.
    Anyway thank you for your response and keep up the good work :) I hope that some day you will be able to write improved version of your sample, maybe transforming it into tutorial. It seems like quite a lot of people could benefit from that.

  • http://orepb.com/tmoksqfz.html Phil Forbes

    hi
    bgrbt9ga2k0lvz5w
    good luck