e y 6 e s : home interface panel : infiniteflight
Download class files and documentation: 'infiniteflight.zip'
Download source code: 'infiniteflightsrc.zip'

InfiniteFlight is a rolling fractal terrain applet; it generates a continuous strip of terrain in a specialized thread, while its main thread lights the terrain and renders it using one of three projections: perspective, isometric, or orthographic. The terrain lighting corresponds roughly to the time of day as read from the host computer's real time clock.

Click the display window with the mouse to cycle between view modes. The perspective view mode employs the classic "heightfield raycasting" algorithm to render the landscape very efficiently. It uses linear interpolation--for both color and height values--to ensure smoothness, and a linear fog function to obscure the terrain passing through the far clip plane (the far edge of the terrain window). The background gradient and fog color are also calculated to coincide roughly with the current time of day. The isometric mode displays a smoothly scrolling section of terrain according to an adaptation of the basic isometric projection. The applet creates the illusion of continuity by displaying a small section of a larger work buffer; this ensures that the drawing edge is hidden from view. The orthographic projection is rendered simply by copying a section of the color buffer into the window.

The applet accomplishes continuous terrain generation using a modified version of the "diamond-square" recursive subdivision algorithm. The terrain generator function builds one third of the entire terrain buffer at a time, while the lighting/rendering thread is progressing between the other two thirds. Terrain continuity is achieved by overlapping the terrain buffer segments--that is, each segment shares a portion of heightfield data with each of its neighbors. The diamond-square process never modifies this first, shared portion; it simply uses it as a seed to construct the rest of the adjacent terrain segment. For performance purposes, I implemented the diamond-square process as an iterative algorithm as opposed to a recursive one, and eschewed Java's Math.random() in favor of an inline integer stochastic function.

The lighting function calculates color values for one line in the heightfield buffer for each frame rendered. This is possible because the light source is defined to be (more or less) fixed; it represents the sun or moon, and so moves imperceptibly slowly. The base terrain color for each height point is obtained by interpolating between a set of two color maps--one for day, and one for night. This base color is then scaled by the dot product of the light vector and the terrain normal (calculated using the adjacent height values). Because the light vector is confined to the x/y plane, the lighting function is also easily able to scan across the heightfield line to accurately calculate which heightfield points lie in the shadow of higher elevations, and to darken them accordingly.

The direction of the light vector and the values contained in the interpolated color lookup table, as well as the background gradient and fog colors used in the perspective view mode, depend on the time of day read from the host computer's real time clock. The applet uses a simplistic model that assumes sunrise to occur at exactly 6:00 AM, and sunset to occur at exactly 6:00 PM. The sun is located due east, with a completely horizontal light vector, at sunrise; its light vector is completely vertical at noon. At sunset, the moon becomes the dominant light source; it is directly overhead at midnight. During most of the day, the sky gradient is cyan-to-white and the fog color is cyan; during the night, the sky is black-to-dark-blue and the fog color is black; at sunrise and sunset, the sky color is cyan-to-purple and the fog color is a darker shade of cyan. When the time is near 6:00 AM or 6:00 PM, all of these colors are interpolated so as to transition smoothly if the applet is run for extended periods of time.
Questions? Comments?