Skip to content

Atmosphere Class

The Atmosphere class manages the context for atmospheric rendering. It automatically calculates the positions of the sun and moon from the configured date and time, and manages textures for atmospheric scattering simulation.

A ThreeView instance holds an instance of this class through the atmosphere property, and atmosphere-related Descriptors such as SunLightDesc, SkyMeshDesc, and AerialPerspectiveEffectDesc reference this instance to operate.

import ThreeView from "@navaramap/three";
const view = new ThreeView({
atmosphere: {
date: new Date("2024-06-21T12:00:00"),
},
});
await view.init();
// Change the date to update the sun position
view.atmosphere.date = new Date("2024-12-21T18:00:00");
// Get the sun direction vector
const sunDirection = view.atmosphere.getSunDirection();
// Get the moon direction vector
const moonDirection = view.atmosphere.getMoonDirection();

Type: Date

Description: The date and time used for sun/moon position calculations. Changing the value automatically recalculates celestial positions.

Default: new Date() (current date and time)

Example:

view.atmosphere.date = new Date("2024-06-21T12:00:00");

Type: Vector3 (read-only)

Description: The current sun direction vector (ECEF coordinate system). It is recommended not to modify this directly, but to obtain a clone using the getSunDirection() method.

Type: Vector3 (read-only)

Description: The current moon direction vector (ECEF coordinate system). It is recommended not to modify this directly, but to obtain a clone using the getMoonDirection() method.

Gets a clone of the sun direction vector.

Syntax:

getSunDirection(): Vector3

Returns:

A new Vector3 instance representing the sun direction in the ECEF coordinate system.

Example:

const sunDir = view.atmosphere.getSunDirection();
console.log("Sun direction:", sunDir.x, sunDir.y, sunDir.z);

Gets a clone of the moon direction vector.

Syntax:

getMoonDirection(): Vector3

Returns:

A new Vector3 instance representing the moon direction in the ECEF coordinate system.

Example:

const moonDir = view.atmosphere.getMoonDirection();
console.log("Moon direction:", moonDir.x, moonDir.y, moonDir.z);

Determines whether a given position is on the night side of the Earth.

Syntax:

isAtNight(position: XYZ): boolean

Parameters:

  • position: The position to evaluate (ECEF coordinate system)

Returns:

true if the position is on the night side, false if on the day side.

Example:

const cameraPosition = view.camera.positionECEF;
const isNight = view.atmosphere.isAtNight({
x: cameraPosition.x,
y: cameraPosition.y,
z: cameraPosition.z,
});
if (isNight) {
console.log("The current location is at night");
}

Returns the sun’s elevation angle in degrees above the local horizon at a location, for the current date. Positive values are above the horizon, negative below (night). Atmospheric refraction is included.

Syntax:

getSunElevation(location: { lat: number; lng: number }): number

Parameters:

  • location: Geographic coordinates in degrees. Only lat and lng are used.

Returns:

The sun elevation in degrees.

Example:

const elevation = view.atmosphere.getSunElevation(view.camera.positionGeographic);
if (elevation < 0) {
console.log("The sun has set.");
}

Returns the local apparent solar time at a longitude, for the current date, in hours in the range [0, 24) where 12 is solar noon. It is derived from the sun’s hour angle, so it accounts for the equation of time.

Syntax:

getSolarTime(location: { lng: number }): number

Parameters:

  • location: Only lng (degrees) affects the result.

Returns:

The local solar time in hours (e.g. 6.3 = 06:18).

Example:

const hours = view.atmosphere.getSolarTime({ lng: 139.69 });

Adjusts date so the local apparent solar time at a longitude equals hours (0–24), keeping the same solar day. It is the inverse of getSolarTime() and is convenient for driving a time-of-day slider whose centre lands on daytime regardless of the viewer’s timezone.

Syntax:

setSolarTime(location: { lng: number }, hours: number): void

Parameters:

  • location: Only lng (degrees) affects the result.
  • hours: Target local solar time in hours (0–24).

Example:

view.atmosphere.setSolarTime({ lng: 139.69 }, 6.3); // sunrise over Tokyo

Adjusts atmosphere.date so that the local solar time at to matches the local solar time at from.

The calculation is based on the sun’s hour angle — the angular distance from the local meridian to the sun. Because hour angle increases monotonically over a solar day, there is exactly one solution per day and no morning/afternoon ambiguity. The equation of time (up to ±16 min difference from simple longitude/15 estimates) is accounted for automatically.

Syntax:

setDateAt(from: { lng: number; lat?: number }, to: { lng: number; lat?: number }): void

Parameters:

  • from.lng: Source longitude in degrees. Only lng affects the result.
  • to.lng: Target longitude in degrees. Only lng affects the result.

Example:

// atmosphere.date represents 08:00 local solar time at Tokyo.
view.atmosphere.setDateAt({ lng: 139.69 }, { lng: 0 });
// → atmosphere.date is now 08:00 local solar time at London (lng = 0°)

Adjusts atmosphere.date so that the sun elevation angle at to matches the sun elevation angle at from.

Unlike setDateAt(), the result depends on latitude because the maximum elevation the sun can reach varies by latitude. The morning/afternoon context (sun rising vs. setting) is preserved based on the solar time at from. If the target elevation exceeds the maximum achievable at to (e.g. during polar night), the date is clamped to solar noon at that location.

Syntax:

setElevationAt(from: { lat: number; lng: number }, to: { lat: number; lng: number }): void

Parameters:

  • from: Source location. Both lat and lng are required.
  • to: Target location. Both lat and lng are required.

Example:

// atmosphere.date shows sun at 30° elevation over Tokyo.
view.atmosphere.setElevationAt({ lat: 35.68, lng: 139.69 }, { lat: 51.5, lng: -0.12 });
// → atmosphere.date adjusted so the sun is also at 30° elevation over London

Convenience wrapper for setDateAt() that uses the current camera position as from.

Syntax:

setDateFromCameraAt(to: { lng: number; lat?: number }): void

Parameters:

  • to.lng: Target longitude in degrees.

Example:

// Camera is over Tokyo. atmosphere.date represents 08:00 local solar time.
view.atmosphere.setDateFromCameraAt({ lng: 0 }); // Adjust to London
// → atmosphere.date is now 08:00 local solar time at London (lng = 0°)
// Fly to a city and synchronise solar time in one step
view.setCamera({ lng: -0.12, lat: 51.5, height: 500, distance: 12000 });
view.atmosphere.setDateFromCameraAt({ lng: -0.12 });

Convenience wrapper for setElevationAt() that uses the current camera position as from.

Syntax:

setElevationFromCameraAt(to: { lat: number; lng: number }): void

Parameters:

  • to.lng: Target longitude in degrees.
  • to.lat: Target latitude in degrees.

Example:

// Camera is over Tokyo with the sun at 30° elevation (morning).
view.atmosphere.setElevationFromCameraAt({ lat: 51.5, lng: -0.12 }); // London
// → atmosphere.date adjusted so the sun is also at 30° elevation over London
// Fly to a city and match the sun elevation
view.setCamera({ lng: -74.01, lat: 40.71, height: 500, distance: 12000 });
view.atmosphere.setElevationFromCameraAt({ lng: -74.01, lat: 40.71 });
setDateAt / setDateFromCameraAtsetElevationAt / setElevationFromCameraAt
What is matchedHour angle (east–west sun position)Elevation angle (height above horizon)
Latitude effectNone — only longitude mattersSignificant — max elevation varies by latitude
Solutions per dayExactly 12 (morning and afternoon) — context preserved automatically
Polar night handlingN/AClamped to solar noon
Typical use”Show the same time of day""Match shadow length and overall brightness”

Fires when the sun direction changes.

Handler Type:

(sunDirection: Vector3) => void

Parameters:

  • sunDirection: The new sun direction vector (clone)

Example:

view.atmosphere.on("sunChanged", (sunDirection) => {
console.log("Sun direction changed:", sunDirection);
});

Atmosphere System Integration with Other Descriptors

Section titled “Atmosphere System Integration with Other Descriptors”

The Atmosphere class automatically integrates with the following Descriptors:

DescriptorIntegration Details
SunLightDescUpdates light direction based on sun direction
SkyMeshDescUpdates rendering positions of the sun and moon
StarsDescUpdates star positions based on sun direction
SkyLightProbeDescCalculates ambient light based on sun direction
AerialPerspectiveEffectDescAerial perspective using atmosphere textures
CloudsEffectDescCloud rendering using atmosphere textures

Atmosphere options that can be specified in the ThreeView constructor:

type AtmosphereOptions = {
/** URL for atmosphere asset files */
atmosphereAssetsUrl?: string;
/** URL for STBN (Spatiotemporal Blue Noise) textures */
stbnUrl?: string;
/** Date and time used for sun/moon position calculations */
date?: Date;
};

Example:

const view = new ThreeView({
atmosphere: {
atmosphereAssetsUrl: "/assets/atmosphere",
stbnUrl: "/assets/stbn",
date: new Date("2024-06-21T12:00:00"),
},
});