I implemented displacement mapping in celestia.Sci.
While this is a prototype and there are still lots of problems, here are some early results from my experiments:
(Top: Stock Moon with normal mapping. Bottom: Displacement mapped Moon with ray traced shadows)
2004-12-18-before2.png [ 290.17 KiB | Viewed 1393 times ]
2004-12-18b2.png [ 276.31 KiB | Viewed 1393 times ]
Detail of Montes Apenninus, slightly brightened in Gimp to match the brightness of the photo reference:
2004-12-18b-detail.png [ 109.95 KiB | Viewed 1393 times ]
Photo reference (source
2004-12-18.jpg [ 221.01 KiB | Viewed 1393 times ]
Shadowed crater (artifacts on the horizon are a known issue):
crater_shadow2.png [ 77.03 KiB | Viewed 1393 times ]
Real-time topographic shading:
topo2.png [ 290.75 KiB | Viewed 1393 times ]
Recently I have been using our lab's stereo display wall to view the surface of the Moon in Celestia.
One thing that immediately struck me was, despite using a high-resolution 128 pix/deg LOLA normal map, that the surface terrain looked incredibly flat
when viewed in stereoscopic 3D, despite the realistic lighting coming from the normal map.
I realized that there were 3 big problems:
- Terrain features lacked parallax, i.e., does not change as it should when the viewpoint changes. I should be able to gradually view the side of a crater rim when rotating around it, but without parallax the crater rim looks pasted in place.
- Despite dark areas being rendered nicely by normal mapping, there were no shadows that moved with the Moon phase.
- The limb of the Moon is a smooth sphere. But as we know, terrain causes the silhouette of the Moon to look jagged.
These are caused by the fact that we are using normal mapping, which only moves the normals of the surface while the terrain geometry is flat. The solution is to really displace the geometry. In computer graphics this is called displacement mapping
There are two main displacement mapping techniques: vertex
Vertex displacement uses vertex texture fetch (VTF)
to read a DEM texture inside the vertex shader, then moving vertices according to texture samples. VTF gained hardware support way back in 2004 so nearly all GPUs have it now. This technique is easy to understand and to implement, but high levels of detail require a large number of polygons. Typically this means a level of detail (LOD) scheme is required to reduce the number of polygons to draw.
I have been playing around with the cdlod algorithm
CD LOD is one of the better LOD schemes (others include Celestia/.Sci's own LOD scheme, geo clip/mipmapping, ROAM, and projective grid mapping) because it is relatively simple, explicitly avoids cracking, and smoothly morphs between successive detail levels. However, very high polygon densities are still required at distances close to the observer, and shadows have to be generated via shadow volumes (which require clipping on concave spherical surfaces like planets and penumbra are complicated to generate) or shadow mapping (which suffers from aliasing and high storage requirements).
Celestia and .Sci does not use VTF, but does apply a LOD scheme to planetary spheres. However a very simple scheme is used; the same LOD is applied to the entire sphere. This results in an excessively high polygon density at far distances, and too few polygons close up.
I also posted previously here on CM about projective grid mapping (PGM), which projects a mesh in screen space; this naturally maps less polygons to far distances. However PGM suffers from shimmering (the terrain appears to swim around like a mirage as the observer moves; this is caused by the geometry "swimming" above the height map), and a very high polygon density is still required when looking straight down on the terrain.
This caused me to look at fragment level displacement techniques. These typically use ray tracing to calculate intersections between rays shot from the observer and a height map. One immediate advantage is far fewer polygons than VTF are required; fragment displacement is limited only by screen size (pixel fill rate). In this example from Smits et al., 1997
(PDF), only 20 triangles
smits97b.jpg [ 13 KiB | Viewed 1393 times ]
Another advantage is that accurate shadows can generated by tracing shadow rays, and the technique can be extended to path tracing for global illumination.
In that paper from 1997, this was before the development of consumer-level GPU shader hardware so the rendering times quoted are on the order of tens of hours per frame using Monte Carlo path tracing. But using GLSL fragment shaders we can do much better. From 2001 to 2005, several important fragment displacement techniques were published starting from Parallax Mapping, Relief Mapping, Parallax Occlusion Mapping (POM), sphere tracing, etc (Szirmay-Kalos and Umenhoffer, 2006
gives a nice overview).
I focused on relief mapping and POM, because the rendering quality is high and complicated and imperfect preprocesing requiring additional time and storage is not required. For example, POM was later extended to generate prisms to extrude surfaces up to enable silhouettes. This is not required if we borrow the curved ray tracing
technique used in Relief Mapping (Oliveira and Policarpo, 2005
[PDF]) and first introduced in Kajiya, 1983
The problem is that all displacement mapping techniques assume a flat base terrain. However, all planetary surfaces have a small, but significant curvature. Instead of dealing with both an arbitrary displaced terrain and a spherical curvature, Kajiya and Oliveira and Policarpo noticed that we could still treat the base terrain as flat, and curve the light rays that we trace instead
(Szirmay-Kalos and Umenhoffer, 2006):
curved_tracing.png [ 34.5 KiB | Viewed 1393 times ]
Frame rates range from 30~60 fps using six 1440x1440 height maps forming a cube. This is with no LOD scheme at all. Currently remaining challenges include eliminating thin artifacts just above the horizon (limb), eliminating flattening of terrain at extreme grazing angles, removing discontinuities at texture borders, and improving shadow quality. Many or all of these may be caused by my naively applying a quadratic approximation (as used by Oliveira and Policarpo) to the sphere curvature.