The current implementation of the planetary renderer uses a single texture, or level of detail (LOD). In order to provide more realistic views when moving closer to the planet's surface I need to vary the LOD according to the view. This is a well-studied and potentially complex topic, however it is useful to start by considering the following:
- A tile system for spherical textures.
- An approach for culling geometry that is not visible.
- An algorithm for picking LOD based on the current view.
- Availability of data.
There are several tiling systems available, however I thought I'd start with a simple quad-tree. Bing maps currently uses 256-pixel, square tiles based on a Mercator projection. The first level has 4 tiles, the second level has 16 tiles etc. Simple cylindrical datasets are also available which use different tile sizes and arrangements, for example 1024-pixel, square tiles with the first level having 2 tiles for east and west, the second having having 8 tiles etc.
I thought I'd start with a simple quad-tree approach, based on culling the results of recursive intersection tests between tile bounding boxes and the view frustum. Figure 1 shows an initial screenshot of this approach. Each of the tiles in a quad is a different primary color, and tiles are drawn for LOD 3 (64 tiles in this tiling scheme). Bounding boxes are shown when there is an intersection at a given LOD with the view frustum. Each child within the bounding box is then checked. If the child is outside of the view frustum, it is culled. If it intersects, the processes recurses to a lower LOD.
The amount of planet surface visible is a function of the distance from the planet, and the field of view and direction of the camera. I therefore needed to work out the size of each tile (they vary by latitude) so that the appropriate LOD can be rendered. I thought I'd start by measuring the maximum distance along a line of longitude within the tile. Figure 2 shows a rendering of the sphere where the upper tiles are rendered at a higher LOD (since for a given LOD they are smaller due to their lattitude).
The geometry used to create the tiles uses a constant number of vertices per degree of latitude and degree of longitude. In addition to minimising vertices, this also ensures that adjacent tiles of different LOD "line-up" correctly to a certain level. For example, if I use 64 vertices per 360 degrees of longitude and 32 vertices per 180 degrees of lattitude, the tiles tesselete without gaps up to LOD 6 in this tiling scheme (since these tiles are the first to have only 4 vertices).
The current planetary renderer uses the following data sources:
- Surface texture
- Normal map
- Cloud map
Going forward, I'd also like to include specularity maps (seperately or as part of the alpha channel of the texture) to deal with the different reflectivity between land and water. In supporting a LOD approach, I don't want to sacrifice realism when rendering lower LOD. Since I would therefore also need normal, cloud (and optionally specularity) maps, I will use the simple cylindrical datasets.