Landscapes
Friday, 22 May 2009.
I've been experimenting with 3D in web browsers lately. And when I say “in”, I really mean in: no plugins, no dependencies, just pure web technologies. So, I revisited a perennial favorite of mine: terrain.
You can get a new landscape by clicking on the map. If you don’t see anything above, you're not using a modern web browser. Give one of these a spin, you won’t be disappointed: Mozilla Firefox, Opera, Apple’s Safari, or Google’s Chrome, all of which are free.
I'm very pleased with the results, considering the limitations of the platform. Canvas presents some interesting challenges for 3D:
Only affine texture mapping is available. This means that the textures on polygons become distorted when viewed at an angle. (If you used to play 3D games on the original Playstation or Sega Saturn, you may recall seeing this exact phenomenon.)
The solution to reducing this problem is to make your polygons as close to equilateral as possible: this will reduce the distortion and present a much smoother surface. (You can also break up offending polygons into multiple, smaller polygons to help fix this.)
Rendering an individual polygon is expensive. The size of the polygon doesn’t appear to matter much; only the fact that you're rendering it. Therefore, the only solution is to keep your polycount very low. Currently, a budget of no more than 80 or so textured polygons seems safe. I hope that browsers continue to optimize their renderers so that this is no longer the bottleneck!
I solved this by structuring my terrain generation algorithm to work directly on the polygon mesh, so that I don’t have to bother with level-of-detail algorithms that produce a high polycount.
All current browsers (except Chrome) produce “seams” between each polygon. This is because they all anti-alias the polygons, and the algorithm used for doing so is inexact. (Chrome does no such antialiasing. Usually, this makes Canvas demos look horrible, but it is actually a boon in this case.)
I have not yet found a satisfactory solution to this problem, as each solution I've tried has its own odd artifacts.
I have some intensity about building an Ogre Battle-esque game to make use of the infinite number of landscapes generated… but that’s for another time.
Source code is available here.
Update 6/01: Much prettier texture mapping, and some optimizations.
Update 6/04: Various optimizations to the terrain generator, and some code cleanup. The polygon rasterizer is respectable now.
Update 6/06: The Perlin noise function is respectable now, too. Some heavy-duty refactoring, and terrain generation improvements (including forested areas).
