I recently saw this video about a game engine that uses normal mapping to generate lighting and shadows for amazing, 3d-like lighting effects. (Like the three barrels below on the right side, they all use a single image, with lighting applied.)

enter image description here

After googling for some time and reading the articles, I'm not sure I understand exactly how this effect works -- that is, how I would implement this. It seems like you need your original image, plus a grey-scale "normal map", where the colour represents depth -- the "farthest away" pixels are black, and the "closest to the viewers" are white.

But even if I have this, how does this information combine with lighting to create that 3D effect?

Also, how would I use this information to create casted shadows (see bottom-left barrels in the picture below)?

  • \$\begingroup\$ Are you sure it is normal mapping and not shadow mapping? \$\endgroup\$ – bobobobo May 5 '12 at 16:44
  • \$\begingroup\$ Bump mapping is bump mapping, whether in 2D or 3D. It works the same way: you have a texture that provides a normal for the surface, rather than interpolating one from vertex positions. \$\endgroup\$ – Nicol Bolas May 5 '12 at 16:53
  • \$\begingroup\$ @bobobobo pretty sure. the author's website mentions that his engine uses normal mapping and focuses on quality lights/shadows. \$\endgroup\$ – ashes999 May 5 '12 at 20:32
  • \$\begingroup\$ @bobobobo shadow mapping is part of it too. I'm more interested in the lighting part though. \$\endgroup\$ – ashes999 May 7 '12 at 2:56
  • \$\begingroup\$ I don't have a full answer, but I found this while thinking about it, so I'm leaving a comment. You'd want at least a 2D normal map, instead of a 3D one like 3D object use, so it wouldn't just be greyscale. Since that's the case, might as well use a full 3D normal map. Then lights that are slightly "behind" the object can still light up things properly. Then I think it's just a matter of applying light according to how close the normal is to the direction of the light, and the distance/output from the light factors in, too. \$\endgroup\$ – William Jan 21 '13 at 19:20

I believe the name of "normal map" may be misleading (i'm not sure), the image itself contains color information which anything can be stored inside R/G/B/A channel and finally name the whole texture to anything totally different.

Anyway please take a look at this similar question. The first comment inside the link below may interest you.

How is 2D lighting implemented?

  • \$\begingroup\$ I've read that link ages ago. It's about shadows, not about simulating 3d via normal mapping. You are correct that the image is pixels, and the channels (R, G, B) are used to store information, not necessarily colour. \$\endgroup\$ – ashes999 May 5 '12 at 20:33

It's close to the exact same as for 3D. If you aren't familiar with 3D graphics programming (including forward lighting, deferred shadong, normal mapping, and shadow mapping) then you should step back and study those topics first. They're all fairly easy; I'd argue that normal mapping is the hardest simply because you have to deal with tangent and binormal basis conversions, but they're just basic linear algebra.

From there, you need to do a few tweaks and simplifications to the algorithms. Assuming you aren't just using a full 3D engine will bill-boarded sprites, that is. First of course is to move from a 3D projection to a 2D projection (simulated using an orthographic projection matrix in a 3D stack combined with keeping all your objects locked in the XY place and oriented toward the positive Z axis). Basic 2D rendering stuff, nothing special at all, but with those 3D lighting algorithms applied in your shaders.

From there, you have a couple small tweaks to make. The most important is your light source location. If your lights are in the XY plane and your objects are in the XY plane and oriented perpendicular to that plane, the lights are going to look "weak". The lighting will look like you laid a flashlight on a table and are trying to light up pages of a book also laying on the same table. The tweak to make then is to simply move the light outward some distance; the distance chosen will need experimentation to find a nice looking value.

For shadowing, the change is to switch from a 2D shadow map to a 1D shadow map. For regular shadow mapping, you project a 3D light source location and direction onto one (or 6, for cube mapping) 2D shadow plane. In 2D lighting, you project a 2D position and direction (just an angle) onto a 1D shadow line. The line can represent the entire 360 degree circumference of the light's affected circle. The math is very similar; all just basic linear algebra. Once you have the shadow line (which contains distances of shadow-casting objects to the light, with each texel corresponding to a particle angle from the light), when rendering any other fragment in the scene, you need only calculate the distance and angle to the light to read from the shadow line and determine if the fragment is in shadow.

It's worth using deferred lighting in 2D, as scenes will generally have lots of lights that affect only a small portion of the scene. The algorithm is basically the exact same between 2D and 3D, expect you replace the planar shadow map lookup with the linear one.

I've yet to use this algorithm in an actual game, but I did build a nice tech demo that looked alright. I'm fairly sure that replacing my coder-art would have made it looked nice.

  • \$\begingroup\$ I would like to see a screenshot of your demo. Most of what you said went over my head, and is contrary to most of the topics I found when googling this topic -- albeit they did not explain in details like you did. \$\endgroup\$ – ashes999 May 5 '12 at 20:34
  • \$\begingroup\$ Do you have links to these topics? I hadnt found any useful ones when I did my demo. The ones I did find did not do shadows the way we wanted to in our actual project (where light was meant to penetrate "walls" with a particular effect, combined with a complex fluid physics rendering. \$\endgroup\$ – Sean Middleditch May 5 '12 at 21:43
  • \$\begingroup\$ I only have the video mentioned in my question. That links to the game engine site, which has additional media. \$\endgroup\$ – ashes999 May 6 '12 at 0:14

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.