Experimenting with WebGL panoramas
We had nice New Year vacations (but so short, unfortunately) at Maple Grove Hot Springs, and between soaking in the nice hot pools I tried the emerging technology I never dealt with before – WebGL, a part of HTML-5 standard that gives you the power of the graphic cards 3-d capability in the browser, programed (mostly) in familiar javaScript. I first searched for the existent panoramas to see how they look like and how responsive they are to the mouse controls, but could not immediately find something working (at least on Firefox 4.0b8 that I just installed – you’ll need to enable “webgl.enabled_for_all_sites” in “about:config” if you would like to try it too). Then I found a nice tutorial with the examples working without a glitch and carefully read the first few lessons.
But I did not have enough patience to go through all of the lessons one by one, so I jumped directly to the lesson that looked most close to what I needed for the panorama that was a model of the Moon that you can rotate with the mouse . So the first experiment was to replace the small texture of the Moon with a much larger one of the panorama made with Eyesis camera. The panorama itself is not perfect – we stitched it manually without enough experience – that is why we have it in smaller resolution on Elphel front page – the stitching errors are easily visible). It did not work immediately – the texture had to have dimensions be power of 2, but with 8192×4096 it showed a nice ball, that rotated with no visible delays.
Next was to get inside that ball, flip it horizontally (from inside the image looks mirrored), change the rotation behavior, so the panorama can be tilted and rotated around strictly vertical axis. And add a new feature – zooming in/out with rotation of the mouse wheel – that was not difficult.
Then I tried to add navigation arrows to be able to go to the next panorama when these arrows are clicked on. Maybe it is possible, but I could not find how to detect objects (arrows) from the viewport 2-d coordinates inside WebGL, so I just applied the same transformation matrices (they are anyway prepared in javaScript before being fed to graphic card memory) to the center coordinates of the arrows and then using the circular hotspots with the certain pixel radius using the mouse coordinates. Switching cursor style (“move”/”pointer”) provides the convenient feedback so you can see when you are clicking on the navigational arrow. The hotspot center still slightly deviates from the center of the arrow when the arrow is near the margins, but that error is small for various zoom values.
To simulate the panorama server I used a small PHP script that used a KML file describing a small set of geo-tagged images, generated a graph connecting the specified nodes and responding with the KML file describing the neighbors of the specified point; the viewer receives that file, uses it for orientation of the panorama and for placing the navigational arrows. When such arrow is clicked on, the viewer sends the new location coordinates to the server, receives the new KML file, generates new arrows and loads the appropriate panorama (texture) images. I’m not yet sure how many images can be cached without Firefox (or other browser) crashing, so there are 2 demo pages:
- caching just 2 panoramas – current and the next ones – geo_test-2.html
- caching 4 panoramas (all currently available on the server) – geo-test.html
We’ll appreciate feedback – do these demos work on your computer/browser/operating system? Are they sluggish or responsive? Crash your browser?
Update:
As no animation is currently used, it is possible to reduce CPU load by redrawing scene only when it is required (something changes), not timer-based.
- caching just 2 panoramas – current and the next ones, no timer, texture interpolation nearest – geo_test-2-notimer.html
- caching 4 panoramas (all currently available on the server), texture interpolation nearest – geo-test4-notimer.html
- caching just 2 panoramas – current and the next ones, texture interpolation linear – geo_test-2-notimer-linear.html
- caching 4 panoramas (all currently available on the server), texture interpolation linear – geo-test4-notimer-linear.html
Update 2 (03/09/2011):
All the different html’s were combined into one file with parameters added:
- caching 2, interpolation:nearest – geo_tests.html?n=2&mag_filter=nearest&min_filter=nearest
- caching 4, interpolation:nearest – geo-tests.html?n=4&mag_filter=nearest&min_filter=nearest
- caching 2, interpolation: linear – geo_tests.html (default paramaters)
- caching 4, interpolation: linear – geo-tests.html?n=4
The parameters are (defaults are in bold):
- n = 2 – number of textures
- mag_filter, min_filter = linear/nearest – interpolation
- timer = true/false – redraw by timer
- longitude, latitude – will work only if the coordinates match with the panorama coordinates
[…] This post was mentioned on Twitter by Alexandre Poltorak, Henrik Bennetsen. Henrik Bennetsen said: RT Experimenting with #WebGL #panoramas http://bit.ly/dJkkB6 […]
I just tried both the demos on Chromium 6.0.472.63 (59945), Debian squeeze (amd64), on a pc with Intel core 2 duo processor and Nvidia GeForce 8600M GT gpu.
Everything is working fine here: nothing crashes and the demos are responsive.
There\’s a little delay after clicking on the arrows (probably caused by data transfer).
One of the two cores of my processor is at 100% usage. I don\’t know if you\’re already doing this or not, but maybe you can change the display strategy so that the scene is not updated if it is not needed (e.g., when there is no user interaction).
Good work!
Giulio.
Giulio,
thank you for the feedback! I’m sorry your reply did not appear immediately – we have the pre-moderation turned on.
I believe the CPU usage can be reduced if the re-drawing of the scene is made per-event, not per-timer how it was in the example from the tutorial I used. That should be easy.
Andrey
[…] Some WebGL panoramas — eat your heart out, Google Street View… […]
Giles,
thank you for the tutorial!
Andrey