We’ve recently made a number of improvements to the atmosphere rendering in CesiumJS.
These changes don’t just make for a prettier scene—though they are pretty. The new atmosphere looks more accurate because it is: like every aspect of CesiumJS, we are striving to create an accurate and precise digital simulation of Earth with excellent web performance. The new atmosphere models are computed on the fly taking into account more complex models of real-world lighting. All these changes were accelerated by the contributions of Xavier Tassin, the creator of GeoFS.
Rendering an accurate atmosphere is an integral part of creating a realistic image of Earth. Whether looking from space or from the ground, we expect to see the bluish gradient of the atmosphere whenever we look at Earth. The appearance of the atmosphere provides key indications about the time of day and gives an important cue for estimating visual distances.
The appearance of the atmosphere comes from atmospheric scattering. Earth’s atmosphere contains air molecules and aerosols such as fog, dust, and air pollutants that scatter sunlight before it reaches our eyes.
The algorithm to simulate atmospheric scattering relies on the principles of volumetric rendering. When light passes through a medium, some of it is absorbed and some of it is scattered. To model this behavior in software, we shoot a ray from the camera to the edge of the atmosphere. After sampling the parts of the ray that are inside the atmosphere, for each sample point we shoot another ray to the edge of the atmosphere towards the light source. This models the amount of light scattered toward the sample position. Summing up the amount of light arriving at each sample position using numerical integration gives the final color of the sky and its intensity.
The scattering of light happens more than once, but for performance reasons, CesiumJS uses single scattering, which is the most dominant and yields a pretty good approximation of the full process. The current implementation relies on the algorithm described by Nishita et. al in 1993 in a paper titled "Display of the earth taking into account atmospheric scattering."
Atmospheric scattering in Earth’s atmosphere occurs because of the scattering of light due to two types of particles: air molecules, which cause Rayleigh scattering, and aerosols, which cause Mie scattering.
Rayleigh scattering accounts for the scattering of light due to particles in the atmosphere that are at least one tenth smaller than the wavelength of the scattered light. In Earth’s atmosphere, these are the air molecules.
The scattering is determined by the equation below:
The key takeaway here is that Rayleigh scattering scales exponentially with the height from the surface of Earth (h) and is highly dependent on the wavelength of the light (𝞴). The smaller the wavelength, the more it will be scattered. This is why the sky appears blue during the day: as the light from the sun goes through the atmosphere, the red and green are scattered away, but the blue remains.
The renderings below show what the atmosphere would look like if green or red had the smallest wavelength.
The phase function for Rayleigh scattering is as follows:
𝝁 is the cosine of the angle between the light and the observation vector. The phase function is primarily used to determine the true atmosphere color by accounting for the direction of the sunlight.
Mie scattering accounts for the scattering of light due to particles in the atmosphere that are bigger in size than the wavelength of the scattered light, such as ozone particles, dust, and pollutants. In Earth’s atmosphere, these are the aerosols, which are found in the lower altitudes of Earth’s atmosphere.
The scattering is determined by the equation below:
We use a simplified version of the Mie scattering equation, where instead of computing the scattering using an integral each time, we simply apply a scale to the observed value of scattering at ground level.
The g here is a constant that is used to control the anisotropy of the medium.
The scattering coefficient is used to determine how much of the light is scattered at a particular height above the ground. The phase function is used to calculate how much of the total light scattered went in a particular direction. To calculate the color of the atmosphere, we start by computing the amount of scattering and apply the phase function for the type of scattering. Adding up the contributions of the Rayleigh and Mie scattering and multiplying it by an intensity factor provides the final color of the atmosphere.
The atmosphere is rendered in two distinct parts in CesiumJS: the sky atmosphere and the ground atmosphere. The sky atmosphere is rendered on an ellipsoid drawn behind the globe with dimensions slightly larger than that of the globe. The ground atmosphere is rendered on the globe when the camera is far away, but when the camera is near Earth’s surface, it is rendered as fog. However, both effects rely on the same algorithm that computes the final color by simulating the process of atmospheric scattering. The relevant code can be found in AtmosphereCommon.glsl.
To allow users to customize the look of the atmosphere, we’ve added properties such as the Rayleigh and Mie scattering constants, Mie anisotropy, and light intensity to the API for the Globe and the SkyAtmosphere.
The recent changes have brought a more accurate rendering of the atmosphere to CesiumJS. To see it in action yourself, check out this Sandcastle that highlights all the customization options available for the atmosphere.