Monday, August 16th, 2010
Tricks From Our Flash Friends: 3D in a 2D Context
<p>If you’ve seen some of the cool work that folks like Mr. Doob or Gerard Ferrandez have done with HTML5/CSS3/SVG/etc., you’ve probably seen them emulating nifty 3D effects in the browser (move your mouse to pan the camera):The demo above, by Gerard, uses SVG plus various mathematical tricks to emulate 3D.
Mr. Doob has a similar demo that emulates 3D but using the Canvas tag using his Three.js library:
What both of these samples have in common is they are using special math to simulate three dimensions on a two-dimensional surface (i.e. our screen using SVG, the Canvas tag, or CSS3 Transforms).
I’ve realized recently that the Flash world is a bit ahead of us in the HTML5 world in terms of doing nifty effects using special tricks such as simulating 3D in a 2D space. I’ve been actually trying to go deep into learning Flash so that I can learn some of these tricks but use them in an HTML5 context.
I reached out to Gerard Ferrandez recently to ask him where he learned the math to do his demos, and he told me he learned them from the Flash world. He pointed me to an absolutely excellent Flash tutorial series that explains in depth how to do such 3D tricks in your own code. It’s straightforward to learn the math but apply it in an HTML5 context. The tutorial series is very complete and easy to understand, basically explaining how to do perspective drawing, first invented in the Renaissance. A classic perspective drawing from the Renaissance:
Notice the lines superimposed on the painting above; shapes that are closer to the viewer are scaled larger, while shapes in the background are smaller. In addition, the location of the shapes on the painting change based on where they located along what is called the ‘vanishing point’. Instead of emulating these with paint, as the Old Masters used to do, we use simple mathematics that can then determine the correct x and y coordinates on our fake 2D ‘window’ in order to simulate a perspective point, then draw it using SVG, Canvas, etc.:
- Exploring 3D in Flash
- Zooming Figures
- Static View with 3D Wire Frame Boxes
- Shape Movement vs. Camera Offset
- Trigonometry
- Panning the Camera
- Simple Camera Panning
- Panning Camera Forward and Backward
- Basic Shading
- Integration of Pre-Rendered 3D Elements
- Trigonometry and Multiple Axes
- Camera Pitch in Viewing Balloon Arches
- Rotation Around A Common Center
- Wire Frame Examples Using the Drawing API
- Shapes and Fills
- Backface Culling
- Solid Pyramids
- Faces and Depths
- Triangular Hourglass and Spaceship
As I continue learning tricks from our Flash friends but in an HTML5 context I’ll keep posting here on Ajaxian.











Some more cool 3D stuff using Canvas and HTML5 – http://bit.ly/canvask3d – commented source code available for download also
The current Safari supports CSS perspective awesomeness. http://webkit.org/blog/386/3d-transforms/.
Actually, a great deal of the Flash tricks came from the early video game era. For Canvas you look back on a great deal of the programming gems from the video gaming world that would go a long way for you today. In fact, I expect what used to take years to develop will now be done in months as we are standing on the shoulders of some rather talented giants. Time to dig out those old game programming gems books.
Why you call it “emulated 3D”. It is perfectly valid 3D. Limited, but the same geometry transformations like on the GPU. You know even OpenGL “emulates” 3D by projecting geometry into the 2D screen surface!
Quite old trick, but nice that it is used with conjunction with SVG for nasty animations!
@Drew81 Yeah the CSS 3D stuff makes things much easier. If you have those then you don’t need to roll the math yourself. However, sometimes you don’t have access to the CSS 3D stuff (such as on Chrome, Firefox, and Android) and need to resort to other solutions.
@Travisalmand I bet there is a treasure trove of great stuff from that era! Someone should go dig some of it up (including the tricks used in old school PC demos) and write up some tutorials online.
@movax I call it emulated 3D because at the end of the day we are faking 3D on a 2D surface (i.e. our screen). If you have WebGL available you don’t necessarily need to do this, but WebGL itself is very low-level and hard to use for simple 3D interfaces.
Hey Brad,
My background is in video game development, I switched to web about 4 years ago when I started to get a whiff of where it was going. Specifically the tag go me excited about the web becoming a great medium for developing visualizations.
Recently I’ve put together two demos that used some of old bag of tricks.
1) One is a demo of a photo with dynamic lighting based on normal maps calculated by a fixed camera and some simple changes of lighting:
http://endergen.com/labs/normal_mapping/beth/
2) Is my incomplete js1k entry, trying to build a 3d racer but damn if I can get it much lower in size and I’m not even near there in functionality: (Arrow keys to control, not finished, but you get the point)
http://endergen.com/labs/js1k/
I’d love to help out if you guys want anyone to write up some intuitive canvas based demos. I’ve always been good at explaining the underlying geometrics of Vector, Matrix, and Quaternion math. Using intuitive visuals.
Just a thought,
Francois (@francoislaberge)
This one still needs to be optimized, I have a good trick figured out but not implemented:
@Brad Neuberg There is no magical 3d context, even with Web(Open)GL.
It’s the same technique: You build a 3d projection matrix & cross your 3d coords through the modelview, & that to get your 2d onscreen vertices.
The only diff is where this occurs (the vertex shader or the cpu).
These aren’t “fake tricks” (nor is this knowledge only existent to flash developers). This is how it’s done.
Welcome to graphics programming :]
(note: when working in gl you can bypass knowledge about the transformations until you need to start modifying vertex shaders, as this is handled for you by default)
Nonetheless it’s nice to see attention being drawn to it.
Let’s see who writes the first textureless OpenGL 1.0 implementation in javascript :]
kinda funny to to say “I call it emulated 3D because at the end of the day we are faking 3D on a 2D surface” But seem to imply that using a 3d API like webGL isn’t emulated?
Anyway still an interesting article :)