7
\$\begingroup\$

I'd like to ask for reference. I met an article about how to cast shadows in games. I'm using html5 canvas (currently without webgl) with javascript for my projects.

The article mentioned above is located at http://willyg302.wordpress.com/2012/11/04/2d-visibility/.

I was thinking if this method is possible to employ with canvas (without webgl) and javascript?

More precisely, I have few shapes drawn on canvas some of them are complex made by arc and similar methods. Thus I don't have a simpel way how to describe one shape with an equation where I can store only a few parametrs (i.e. circle is described as centerX, centerY, radius with these I can easily draw it but with more complex shapes I don't have such information) therefore I thought about storing the whole canvas data by pixels with context.getImageData.data, then using method described in the article (polar transformation, ..., back to cartesian system) and putting the whole scene into canvas with canvas.putImageData method.

But before actually applying this I'd like to ask if it's even possible with canvas (no webgl) and javascript to create shadows dynamically (light source moving across the screen) this way without heavy fps loss (I can imagine this method works pretty good for still objects but the moment when I need to do it each time a light source moves I'm not sure if javascript + canvas can handle this in reasonable time, especially when I found information that putImageData and getImageData are quite slow)?

Or if anyone has tried to create dynamic shadows in different way in html5+js I'd appreciate your suggestions about these as well (I do it currently in similar way as is described in http://ncase.me/sight-and-light/, though I'm experiencing some troubles with concave shapes :( ).

This is getting awfully long, I hope I explained myself well enough.

Thank you very much for any advice you can share and I'm sorry that my post grew so large, although I'm asking just one question.

EDIT: Forgot to mention, I'm looking only for 2d solution.

\$\endgroup\$
  • \$\begingroup\$ What kind of "trouble" do you experience with concave shapes? \$\endgroup\$ – Philipp Nov 20 '14 at 8:29
  • \$\begingroup\$ Well currently I have problems with any more complex shape which is not made of line segments (not only concave, I was just using it as a reference). I'm using arc for some shapes which results in crescent shapes. These shapes are hard for me to deal with because I can't use a two point strategy as is described in the link I posted before (thought I was able to apply it for circles, when it comes to semicircles - crescent-shaped - I'm lost), thus I was looking for a different solution to try out. \$\endgroup\$ – Petr Nov 20 '14 at 15:21
  • \$\begingroup\$ Old question, but for SVG type paths I have a collection of algorithms here: github.com/sirisian/svg-shadows that might be useful if you're trying to implement arbitrary 2D shadows. That project was just designed to cast shadows at a 45 degree angle, but most of the algorithms are generic. I also have this: sirisian.com/javascript/lighting.html but it only works for lines and generates light volume regions. Could be made to work with curves though with a bit of work. The algorithm used there is kind of generic. \$\endgroup\$ – Sirisian May 2 '16 at 19:30
1
\$\begingroup\$

Well, that's a tricky question but I'll start from the beginning.

  • Get/Put imageData is faster than you think, but if you want to do it in a efficient way I'd recomend you to build a double buffer and rasterize your shapes in it (here's a double buffer module I wrote, have a peek).

  • Strange shapes' shadowing is as hard to do as rectangles shadowing, you only need to set a light point, then raycast it (raycast module i wrote, maybe it will help you to find out how to do it) and get the angle of the shadows for each object, then, thinking in objects as 3D and having the light point's 3D coords, project the object's shadow into the floor in said angle from it's bottom.

Usually, 2D games use baked shadows though, as it's easier to manage and implement than dynamic shadows.

If you want to do dynamic shadows, I'd recommend you to build everything in 3D and then render it by projection, I built a 3D rasterizer for vanilla 2D canvas that could help you, it renders 3D triangulated meshes in 2D canvas by projection, I have a updated version with dynamic shadowing and some other stuff, tell me if you are interested and I'll upload it later, and yes, it works in a good FPS rate, but you can't use the canvas render API for this purpose since you have to manage pixels.

Good luck.

\$\endgroup\$
0
\$\begingroup\$

I've thought about this for a while, I have have done a bit of research on this topic. Other than using a framework and writing super complex/long code, there are two options that I can think of:

  1. use shadowblur
  2. use radial/linear gradients

http://www.w3schools.com/tags/canvas_createradialgradient.asp

Another option is to use alpa colors to draw various levels of darkness such as squares or circles:

context.save();
context.globalAlpha = 0.5;
context.fillStyle = "#000000";
// draw a whole ton of shapes with 50% transparency with a black color...
context.restore();
\$\endgroup\$

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.