Normal Mapping with Javascript and Canvas
I made a little experiment with normal mapping and phong shading in javascript which turned out to work quite well. I think with a little bit of tweaking it could be used in a real time game. Just move your mouse over the images bellow to see it in action. You'll need a modern browser supporting the canvas tag for this to work. Google Chrome seems to be the fastest.
Demo
Source
You can view the source code here: light.js. Feel free to copy from it, but please notify me if you use it for something cool. :) Also beware that the code is pretty hacky and unpolished.
How it works
The 3D effect is basically created using 2 textures. One contains the color of each pixel and the other the surface normal. The color image is rendered using only indirect lighting (ambient occlusion in that case). The direct light is then calculated in real time using phong shading without the diffuse part. For a more accurate description, read the source. ;)


Credits
The dragon head used in this demo comes from planetpixelemporium.com. The Buddah is from the Stanford 3D Scanning Repository and was rendered and baked using blender. Thanks for letting me use it.
Jonas Wagner
Whoa!
Comment by Skofo — 3/26/10 3:09 AM | # - re
Impressive effect ! :) I can't wait for watching this code
Comment by HALIMI Jean-Philippe — 3/26/10 1:23 PM | # - re
Awesome!
Comment by Diego Betto — 3/26/10 1:55 PM | # - re
awesome! yay!
Comment by MyFreeWeb — 3/26/10 2:15 PM | # - re
cool effect! but i'm little confused where it can be used in real html pages
Comment by peter — 3/26/10 2:33 PM | # - re
It seems little bit slow compared to Flash?
www.derschmale.com/demo/bumpmapping/bump2D.html
Comment by Tomas — 3/26/10 3:02 PM | # - re
yes but here it`s java script and there is macromedia flash or CS3. ;)
Comment by alex — 5/5/10 9:18 AM | # - re
Not using Google Chrome. (But extremely slow when using Firefox, even when using the latest nightly build.)
Comment by panzi — 10/5/10 2:31 AM | # - re
It will be fast once jaegermonkey is reintegrated.
Comment by Jonas Wagner — 10/5/10 4:42 PM | # - re
This is really nice. I like the code behid it.
Comment by Thorsten — 3/26/10 3:11 PM | # - re
Wow, that is a pretty impressive looking effect!
Now, who can come up with a practical use for this? =)
Comment by Jani Hartikainen — 3/26/10 3:16 PM | # - re
I think with some tweaking it can be used in a 2d game. Also, with webgl this will be possible without any hit on the CPU.
Comment by Jonas Wagner — 3/26/10 3:26 PM | # - re
Amazing job dude!
Comment by Schalk Neethling — 3/26/10 3:23 PM | # - re
That is slick
Comment by John Allen — 3/26/10 3:47 PM | # - re
I have touchscreen you insensitive clod! Can't see the effect :(
Comment by jl — 3/26/10 3:53 PM | # - re
Tomas, I don't see a difference in performance on my system. Nice work Jonas!
Comment by Bill — 3/26/10 4:22 PM | # - re
jl, its probably because you have a computer that average persons not have. Don't forget that there is really a jungle of browsers and performance in javascript
Comment by Tomas — 3/29/10 1:33 PM | # - re
this is good - but it only changes the pixels and you can do the alpha
you can even mix two pictures.i am sure you know
if u dont let me know ..
cheers
olga lednichenko
nesher-israel
Comment by Olga Lednichenko — 3/26/10 5:41 PM | # - re
Incredible, liquid smooth in Safari for me, but really chugs in Firefox.
Comment by Ian — 3/26/10 7:07 PM | # - re
Holy cow I'm impressed! I take it it squeeze the juice out of my poor CPU :)
Comment by vsync — 3/27/10 7:16 PM | # - re
Wow, It's great.
Comment by Jongsin Yoon — 3/29/10 7:16 AM | # - re
Good effect.
Comment by 潮流 — 3/29/10 7:45 AM | # - re
cpu hog. slow. but amazing.
Comment by Tim — 3/29/10 7:11 PM | # - re
Wow amazing.~~
Comment by jhlee — 3/29/10 7:41 PM | # - re
unbelievable!!!
Comment by wang — 3/30/10 5:16 AM | # - re
Daaaaamn! That it is crazy awesome!
Comment by Ilia — 3/30/10 5:43 PM | # - re
awesome ! make me think about sylvester.jcoglan.com/ to perform vector calculations. did you know it ?
Comment by challet — 3/31/10 6:05 PM | # - re
Yeah I did, but I think it's an overkill for what I needed. Plus it's probably slower.
Comment by Jonas Wagner — 3/31/10 6:23 PM | # - re
so great .... ill try myself...
Comment by ralu rm — 5/7/10 12:48 PM | # - re
Wow! Very cool!
Out of curiosity, why the abs function? Math.abs() should work just as well (if not perhaps a bit faster)?
Cheers!
Comment by Amadeus — 5/26/10 7:34 AM | # - re
Because I linked to the wrong file! I fixed the link now. Thanks for letting me know.
Comment by Jonas Wagner — 5/26/10 10:29 AM | # - re
Impressive indeed.
Comment by Nordvind — 6/2/10 12:33 PM | # - re
This is really fantastic. Well done.
Comment by Genkilabs — 6/11/10 12:29 AM | # - re
Seems there is a massive performance regression with firefox 4.6b6pre nightly vs firefox 3.6.8 :( It also seems that this regression has existed for quite a while.
Comment by Mark — 9/10/10 1:16 AM | # - re
The notion that this doesn't work well on Firefox is bullshit, I can run it just fine.
Comment by Ben — 2/10/11 6:29 PM | # - re
Things change in a year. ;)
Comment by Jonas Wagner — 2/11/11 9:00 AM | # - re
Great!!!
(W Blender!)
Comment by Qwerty — 2/16/11 10:46 PM | # - re
that is freakin' amazing... Very cool
Comment by jefe — 3/16/11 5:42 AM | # - re
We're using this effect on our homepage:
www.zebradog.com
Did a few optimizations as well, which seemed to significantly increase performance. You can see the comparison here:
zebradog.github.com/demo/normal-mapping/
Comment by Matt Cook — 7/5/11 10:31 PM | # - re
gravytea.com/labs/dementia/
I used negative color intensities to make as if color was sucked out of the face (except red component).
Why do you clamp the color values? It looks like Chrome and Firefox do it by themselves faster than a JS implementation...
Florian
Comment by Florian — 11/14/11 1:44 PM | # - re
Not all of them were doing it back when I implemented it. No idea what the status is now.
Comment by Jonas Wagner — 11/14/11 3:22 PM | # - re
Runs fine on Firefox 8. Looks completely awesome. Good job!
Comment by Lynda — 11/15/11 3:05 AM | # - re