I want to add lighting to an isometric game that I'm working on.


The closest I've come so far is to do a pass over the blocks on the floor and build up a light intensity matrix (based on how far each one is from the nearest light source). Then I've been rendering that with overlay compositing enabled.

enter image description here

This sort of works as a rough prototype, but there are some problems and I don't know whether they're inherent limitations of the way I'm storing the scene.

The floor blocks are stored in a 2d array and the world entities are stored in a list with their own 2d coordinates and height.

That means that if I overlay a light map like I did in the example earlier, the shadow only covers the tile. Entities on the tile are only partially effected by that tile's light value.

Here's an example where the blue tile is the overlaying light tile without blending turned on.

enter image description here

If that character was at the edge of the map, the top half of their body would be unaffected by the lighting.

I could trace rays out through the scene and mark the colliding faces with lightness values, but at that point, I'm not sure how I'd actually render that lightmap onto the screen.

How can I construct a light map that can be rendered over this scene?

  • \$\begingroup\$ Does the light map need to be rendered over the map, or could you use the light values looked up from the light map to tint each tile/object as you draw them? \$\endgroup\$ – DMGregory Mar 18 '18 at 18:48
  • \$\begingroup\$ Could do either. \$\endgroup\$ – Dan Prince Mar 18 '18 at 18:56

A better, yet very similar approach, would be applying the light matrix during the sprite rendering, tinting it with overlay blending using the sampled position of the tile it belongs to. That way, not only will you prevent the issue at the edge of the map, but also, tall sprites will correctly be affected by the tile they belong to, instead of having their tall parts use the light from whatever tile is behind them.

  • \$\begingroup\$ Getting very close i.imgur.com/Xc6hu76.png \$\endgroup\$ – Dan Prince Mar 19 '18 at 0:29
  • \$\begingroup\$ @DanPrince Yep! that's the concept. You still have some things to sort out on the northeastmost part of the map. Unless those are semitransparent tiles, in which case it's fine. \$\endgroup\$ – Kroltan Mar 19 '18 at 0:30
  • \$\begingroup\$ Yeah, there are three rows of semitransparent tiles along the north side of the map. \$\endgroup\$ – Dan Prince Mar 19 '18 at 0:39
  • \$\begingroup\$ i.imgur.com/wveiYbv.png I think it's there. Now I've just got to deal with the 10x performance hit. Currently drawing the light value to a separate canvas, then using that as a mask for the sprite, before drawing the masked colour onto the canvas and blending the sprite onto that. Any ideas for making that simpler? \$\endgroup\$ – Dan Prince Mar 19 '18 at 0:53
  • \$\begingroup\$ @DanPrince Not sure about HTML canvas, but I don't think you need to mask the sprite's tint. \$\endgroup\$ – Kroltan Mar 19 '18 at 0:53

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.