Level of Detail

20 Mar 2011 18:49
Last Modified
13 Jan 2013 17:40

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:

Tile System

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.

AABB Intersections with View Frustum

Figure 1. AABB Intersections of Tiles with View Frustum

LOD Calculation

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).


Figure 2. Tiles rendered at varying LOD

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:

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.


17 Apr 2012 00:43
Hi Dave, I'm having trouble seeing how you are getting from a particular AABB to the actual tiles. The AABB divide up the latitudes cleanly, so each AABB maps exactly to a particular 'row' of tiles in an associated LOD tileset. But which tiles in the row doesn't seem to come cleanly once you've gone below four tiles in the row - after that e.g. 8 tiles in a slice it seems the AABB require several tiles to cover their part of the sphere. Am I missing something simpler here? Awesome work btw. Bunter.
25 May 2012 21:20
Thanks Bunter :) I precalculate the AABB's and do recursive intersection tests with the view frustum.
26 Dec 2012 16:22
Would you be willing to share any code, or examples of how you are able to generate your planet sphere coordinates and also how you perform the quadtree calculations? At minimum, can you point me to some sources that you used to learn these concepts - I'm kind of struggling to do something similar (although in Java with JOGL/OpenGL). Thanks.
28 Dec 2012 16:55
Let me clarify my earlier question/request...I'm trying to do build in the LOD tiling system that you have already implemented. I want to be able to zoom in to my Earth and have the tiles regenerate based on the LOD value but I can't seem to figure out how best to do it. I initially looked at simple quad sphere generation starting from a cube - not sure of the proper terminology. But I realized that even though subdividing a cube and then the subsequent quads will generate an nicer sphere, i would not know how to apply the equirectangular map tiles to that kind of sphere. So I realized I need to be back to using the similar sphere geometry you have but I'm not sure how best to proceed with the subdivisions as you zoom in and how that should be stored internally...any help/direction would be appreciated.
2 Jan 2013 15:06
Hi Mariuz, I'm not sure of the best way, but I can expand on the approach I took :) I subdivide a sphere by equally divisions in latitude and longitude, so that I can use a standard texture-tiling mechanism based on equirectangular projections. For each subdivision in a given level, I pregenerate the geometry, calculate its axis-aligned bounding box, and recurse to its four children to build up a quad-tree. When I render the planet, I start from the first level, then test each subdivision's bounding box within that level for an intersection with the view frustum. If it intersects, or the size of the subdivision is below some threshold (which depends on the screen resolution and tile texture size), I recurse to the subdivision's four children, and so on. I'm sorry, but I don't have any sample code available at the moment. Hope this helps and best wishes, Dave.

Add Comment