Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@takram/three-atmosphere

A Three.js and R3F implementation of Precomputed Atmospheric Scattering

three, three.js, geospatial, atmosphere, sun, sky

readme

@takram/three-atmosphere

npm version Storybook

A Three.js and R3F (React Three Fiber) implementation of Eric Bruneton’s Precomputed Atmospheric Scattering.

This library is part of a project to prototype the rendering aspect of a Web GIS engine. For more details on the background and current status of this project, please refer to the main README.

Installation

npm install @takram/three-atmosphere
pnpm add @takram/three-atmosphere
yarn add @takram/three-atmosphere

Peer dependencies include three and postprocessing, as well as @react-three/fiber, @react-three/postprocessing, and @react-three/drei when using R3F.

three postprocessing
@react-three/fiber @react-three/postprocessing @react-three/drei

Usage

Post-process lighting

Suitable for large-scale scenes, but supports only Lambertian BRDF.

Lighting is applied in AerialPerspectiveEffect. Materials must be unlit (e.g. MeshBasicMaterial) and the render buffer is considered albedo.

import { EffectComposer } from '@react-three/postprocessing'
import {
  AerialPerspective,
  Atmosphere,
  Sky
} from '@takram/three-atmosphere/r3f'

const Scene = () => (
  <Atmosphere date={/* Date object or timestamp */}>
    <Sky />
    <mesh>
      <meshBasicMaterial />
    </mesh>
    <EffectComposer enableNormalPass>
      <AerialPerspective sunIrradiance skyIrradiance />
    </EffectComposer>
  </Atmosphere>
)

Example of post-process lightingStorybook

Example of post-process lightingStorybook

Light-source lighting

Compatible with built-in Three.js materials and shadows, but both direct and indirect irradiance are approximated only for small-scale scenes.

Objects are lit by SunDirectionalLight, SkyLightProbe, and possibly other light sources.

import { EffectComposer } from '@react-three/postprocessing'
import {
  AerialPerspective,
  Atmosphere,
  Sky,
  SkyLight,
  SunLight
} from '@takram/three-atmosphere/r3f'

const Scene = () => (
  <Atmosphere date={/* Date object or timestamp */}>
    <Sky />
    <group position={/* ECEF coordinate in meters */}>
      <SkyLight />
      <SunLight />
    </group>
    <mesh>
      <meshPhysicalMaterial />
    </mesh>
    <EffectComposer>
      <AerialPerspective />
    </EffectComposer>
  </Atmosphere>
)

Example of light-source lightingStorybook

Mixed lighting

Selectively applies the post-process and light-source lighting using IrradianceMaskPass or an MRT texture. It combines the advantages of both, but transparency over the post-process lighting is not supported.

import { EffectComposer } from '@react-three/postprocessing'
import {
  AerialPerspective,
  Atmosphere,
  IrradianceMask,
  Sky,
  SkyLight,
  SunLight
} from '@takram/three-atmosphere/r3f'
import { Layers } from 'three'

const IRRADIANCE_MASK_LAYER = 10
const layers = new Layers()
layers.enable(IRRADIANCE_MASK_LAYER)

const Scene = () => (
  <Atmosphere date={/* Date object or timestamp */}>
    <Sky />
    <group position={/* ECEF coordinate in meters */}>
      <SkyLight />
      <SunLight />
    </group>
    <mesh>
      {/* This mesh is lit in post-process. */}
      <meshBasicMaterial />
    </mesh>
    <mesh layers={layers}>
      {/* This mesh is lit by light sources. */}
      <meshPhysicalMaterial />
    </mesh>
    <EffectComposer enableNormalPass>
      <IrradianceMask selectionLayer={IRRADIANCE_MASK_LAYER} />
      <AerialPerspective sunIrradiance skyIrradiance />
    </EffectComposer>
  </Atmosphere>
)

Example of mixed lightingStorybook

Transient update by date

import { useFrame } from '@react-three/fiber'
import {
  Atmosphere,
  Sky,
  type AtmosphereApi
} from '@takram/three-atmosphere/r3f'
import { useRef } from 'react'

const Scene = () => {
  const atmosphereRef = useRef<AtmosphereApi>(null)
  useFrame(() => {
    atmosphereRef.current?.updateByDate(new Date())
  })
  return (
    <Atmosphere ref={atmosphereRef}>
      <Sky />
      ...
    </Atmosphere>
  )
}

Vanilla Three.js

See the story for complete example.

const position = new Vector3(/* ECEF coordinate in meters */)

// SkyMaterial disables projection. Provide a plane that covers clip space.
const skyMaterial = new SkyMaterial()
const sky = new Mesh(new PlaneGeometry(2, 2), skyMaterial)
sky.frustumCulled = false
sky.position.copy(position)
scene.add(sky)

// SkyLightProbe computes sky irradiance of its position.
const skyLight = new SkyLightProbe()
skyLight.position.copy(position)
scene.add(skyLight)

// SunDirectionalLight computes sunlight transmittance to its target position.
const sunLight = new SunDirectionalLight()
sunLight.target.position.copy(position)
scene.add(sunLight)
scene.add(sunLight.target)

// Demonstrates light-source lighting here. For post-process lighting, set
// sunIrradiance and skyIrradiance to true, remove SkyLightProbe and
// SunDirectionalLight, and provide a normal buffer to AerialPerspectiveEffect.
const aerialPerspective = new AerialPerspectiveEffect(camera)

// Use floating-point render buffer, as radiance/luminance is stored here.
const composer = new EffectComposer(renderer, {
  frameBufferType: HalfFloatType
})
composer.addPass(new RenderPass(scene, camera))
composer.addPass(
  new EffectPass(
    camera,
    aerialPerspective,
    new ToneMappingEffect({ mode: ToneMappingMode.AGX })
  )
)

const texturesLoader = new PrecomputedTexturesLoader()
texturesLoader.setTypeFromRenderer(renderer)
texturesLoader.load('/assets', textures => {
  Object.assign(skyMaterial, textures)
  sunLight.transmittanceTexture = textures.transmittanceTexture
  skyLight.irradianceTexture = textures.irradianceTexture
  Object.assign(aerialPerspective, textures)
})

const sunDirection = new Vector3()
const moonDirection = new Vector3()

function render(): void {
  // Suppose `date` is updated elsewhere.
  getSunDirectionECEF(date, sunDirection)
  getMoonDirectionECEF(date, moonDirection)

  skyMaterial.sunDirection.copy(sunDirection)
  skyMaterial.moonDirection.copy(moonDirection)
  sunLight.sunDirection.copy(sunDirection)
  skyLight.sunDirection.copy(sunDirection)
  aerialPerspective.sunDirection.copy(sunDirection)

  sunLight.update()
  skyLight.update()
  composer.render()
}

Limitations

  • The reference frame is fixed to ECEF and cannot be configured, #11.

  • The viewpoint is restricted to positions above the atmosphere’s inner sphere. It doesn’t render correctly underground, #5.

  • The aerial perspective (specifically the inscatter term) includes a workaround for the horizon artifact, but due to finite floating-point precision, this artifact cannot be removed completely.

  • Volumetric light shaft is not implemented as it requires ray tracing or an additional depth pass from the sun. You may notice scattered light is not occluded by scene objects.

  • Although you can generate custom precomputed textures, the implementation is effectively limited to Earth’s atmosphere. For rendering atmospheres of other planets, consider implementing Sébastien Hillaire’s A Scalable and Production Ready Sky and Atmosphere Rendering Technique.

  • Currently developed using GLSL. It does not use node-based TSL yet, and WebGPU is not supported, but both are planned.

API

The underlying concepts of these components and classes might be a bit complex. If you have any questions, feel free to ask in the Issues or Discussions.

R3F components

Three.js

Functions

Atmosphere

Provides and synchronizes props of atmosphere components. It’s the recommended way to configure components unless you need finer control over properties of individual components.

Source

import { useFrame } from '@react-three/fiber'
import {
  Atmosphere,
  Sky,
  useAtmosphereTextureProps,
  type AtmosphereApi
} from '@takram/three-atmosphere/r3f'
import { useRef } from 'react'

const Scene = () => {
  const atmosphereRef = useRef<AtmosphereApi>(null)
  useFrame(() => {
    // Computes sun direction, moon direction and ECI to ECEF rotation
    // matrix by the date, then propagates them to descendant components via
    // context.
    atmosphereRef.current?.updateByDate(new Date())
  })

  // The choice of precomputed textures depends on whether single-precision
  // float or half-float textures are supported. Some devices don't support
  // single-precision textures, so this hook fallbacks to half-float textures
  // when necessary.
  const textureProps = useAtmosphereTextureProps('/assets')
  return (
    <Atmosphere ref={atmosphereRef} {...textureProps}>
      <Sky />
      ...
    </Atmosphere>
  )
}

Props

textures

textures: PrecomputedTextures | string = DEFAULT_PRECOMPUTED_TEXTURES_URL

The precomputed textures, or a URL to the directory containing them.

If left undefined, the textures will be loaded directly from GitHub.

ellipsoid

ellipsoid: Ellipsoid = Ellipsoid.WGS84

The ellipsoid model representing Earth.

correctAltitude

correctAltitude: boolean = true

Whether to adjust the atmosphere’s inner sphere to osculate (touch and share a tangent with) the ellipsoid.

The atmosphere is approximated as a sphere, with a radius between the ellipsoid’s major and minor axes. The difference can exceed 10,000 meters in worst cases, roughly equal to the cruising altitude of a passenger jet. This option compensates for this difference.

An example at an altitude of 2,000 meters and a latitude of 35°:

correctAltitude = false correctAltitude = true

photometric

photometric: boolean = true

Whether to store luminance instead of radiance in render buffers.

photometric = false photometric = true

date

date: number | Date = undefined

Specifies the date used to obtain the directions of the sun, moon, and ECI to ECEF rotation matrix.

The behavior when used together with the updateByDate function is not defined.

Ref

sunDirection, moonDirection

sunDirection: Vector3
moonDirection: Vector3

The normalized direction to the sun and moon in ECEF coordinates. This value is shared with descendant components and is overwritten by the date prop or the updateByDate function.

The default values are [0, 0, 0].

rotationMatrix

rotationMatrix: Matrix4

The rotation matrix for converting ECI to ECEF coordinates. This value is shared with descendant components and is overwritten by the date prop or the updateByDate function.

The default value is an identity matrix.

ellipsoidCenter, ellipsoidMatrix

ellipsoidCenter: Vector3
ellipsoidMatrix: Matrix4

The center coordinates and rotation matrix of the ellipsoid. Use these values to define a reference frame or, more commonly, to move the ellipsoid for working around the world space origin and adapting to Three.js’s Y-up coordinate system.

The default value of ellipsoidCenter is [0, 0, 0], and ellipsoidMatrix is an identity matrix.

import { type AtmosphereApi } from '@takram/three-atmosphere/r3f'
import { Ellipsoid } from '@takram/three-geospatial'
import { Vector3 } from 'three'

const position = new Vector3(/* ECEF coordinate in meters */)
const east = new Vector3()
const north = new Vector3()
const up = new Vector3()

declare const atmosphere: AtmosphereApi

// Offset the ellipsoid so that the world space origin locates at the
// position relative to the ellipsoid.
atmosphere.ellipsoidCenter.copy(position).multiplyScalar(-1)

// Rotate the ellipsoid around the world space origin so that the camera's
// orientation aligns with X: north, Y: up, Z: east, for example.
Ellipsoid.WGS84.getEastNorthUpVectors(position, east, north, up)
atmosphere.ellipsoidMatrix.makeBasis(north, up, east).invert()

See the story for complete example.

updateByDate

function updateByDate(date: number | Date): void

Updates the directions of the sun, moon, and the ECI to ECEF rotation matrix for the specified date. Use this function via the ref instead of the date prop if you want to update it smoothly.

The behavior when used together with the date prop is not defined.

Sky

Displays the sky in a screen quad.

See SkyMaterial for further details.

Source

import { useLoader } from '@react-three/fiber'
import {
  getMoonDirectionECEF,
  getSunDirectionECEF,
  PrecomputedTexturesLoader
} from '@takram/three-atmosphere'
import { Sky } from '@takram/three-atmosphere/r3f'

const sunDirection = getSunDirectionECEF(/* date */)
const moonDirection = getMoonDirectionECEF(/* date */)

const Scene = () => {
  const precomputedTextures = useLoader(PrecomputedTexturesLoader, '/assets')
  return (
    <Sky
      {...precomputedTextures}
      sunDirection={sunDirection}
      moonDirection={moonDirection}
    />
  )
}

Props

The parameters of AtmosphereMaterialBase and SkyMaterial are exposed as props.

Stars

Represents the brightest stars as points at an infinite distance.

See StarsMaterial for further details.

Source

import { useLoader } from '@react-three/fiber'
import {
  getECIToECEFRotationMatrix,
  getSunDirectionECEF,
  PrecomputedTexturesLoader
} from '@takram/three-atmosphere'
import { Stars } from '@takram/three-atmosphere/r3f'
import { ArrayBufferLoader } from '@takram/three-geospatial'

const sunDirection = getSunDirectionECEF(/* date */)
const rotationMatrix = getECIToECEFRotationMatrix(/* date */)

const Scene = () => {
  const precomputedTextures = useLoader(PrecomputedTexturesLoader, '/assets')
  const starsData = useLoader(ArrayBufferLoader, '/assets/stars.bin')
  return (
    <Stars
      {...precomputedTextures}
      data={starsData}
      sunDirection={sunDirection}
      matrix={rotationMatrix}
    />
  )
}

Props

The parameters of AtmosphereMaterialBase and StarsMaterial are also exposed as props.

data

data: ArrayBuffer | string = DEFAULT_STARS_DATA_URL

The data containing the position and magnitude of the stars, or a URL to it.

If left undefined, the data will be loaded directly from GitHub.

SkyLight

A light probe for indirect sky irradiance.

See SkyLightProbe for further details.

Source

import { useLoader } from '@react-three/fiber'
import {
  getSunDirectionECEF,
  IRRADIANCE_TEXTURE_HEIGHT,
  IRRADIANCE_TEXTURE_WIDTH
} from '@takram/three-atmosphere'
import { SkyLight } from '@takram/three-atmosphere/r3f'
import {
  createDataTextureLoaderClass,
  parseFloat32Array
} from '@takram/three-geospatial'
import { Vector3 } from 'three'

const position = new Vector3(/* ECEF coordinate in meters */)
const sunDirection = getSunDirectionECEF(/* date */)

const Scene = () => {
  const irradianceTexture = useLoader(
    createDataTextureLoaderClass(parseFloat32Array, {
      width: IRRADIANCE_TEXTURE_WIDTH,
      height: IRRADIANCE_TEXTURE_HEIGHT
    }),
    '/assets/irradiance.bin'
  )
  return (
    <SkyLight
      irradianceTexture={irradianceTexture}
      position={position}
      sunDirection={sunDirection}
    />
  )
}

Props

The parameters of SkyLightProbe are exposed as props.

SunLight

A directional light representing the sun.

See SunDirectionalLight for further details.

Source

import { useLoader } from '@react-three/fiber'
import {
  getSunDirectionECEF,
  TRANSMITTANCE_TEXTURE_HEIGHT,
  TRANSMITTANCE_TEXTURE_WIDTH
} from '@takram/three-atmosphere'
import { SunLight } from '@takram/three-atmosphere/r3f'
import {
  createDataTextureLoaderClass,
  parseFloat32Array
} from '@takram/three-geospatial'
import { Vector3 } from 'three'

const position = new Vector3(/* ECEF coordinate in meters */)
const sunDirection = getSunDirectionECEF(/* date */)

const Scene = () => {
  const transmittanceTexture = useLoader(
    createDataTextureLoaderClass(parseFloat32Array, {
      width: TRANSMITTANCE_TEXTURE_WIDTH,
      height: TRANSMITTANCE_TEXTURE_HEIGHT
    }),
    '/assets/transmittance.bin'
  )
  return (
    <SunLight
      transmittanceTexture={transmittanceTexture}
      position={position}
      sunDirection={sunDirection}
    />
  )
}

Props

The parameters of SunDirectionalLight are exposed as props.

AerialPerspective

A post-processing effect that renders atmospheric transparency and inscattered light.

See AerialPerspectiveEffect for further details.

Source

import { useLoader } from '@react-three/fiber'
import { EffectComposer } from '@react-three/postprocessing'
import {
  getSunDirectionECEF,
  PrecomputedTexturesLoader
} from '@takram/three-atmosphere'
import { AerialPerspective } from '@takram/three-atmosphere/r3f'
import { Vector3 } from 'three'

const sunDirection = getSunDirectionECEF(/* date */)

const Scene = () => {
  const precomputedTextures = useLoader(PrecomputedTexturesLoader, '/assets')
  return (
    <EffectComposer>
      <AerialPerspective {...precomputedTextures} sunDirection={sunDirection} />
    </EffectComposer>
  )
}

Props

The parameters of AerialPerspectiveEffect are exposed as props.

IrradianceMask

A post-processing pass that renders a mask for the mixed lighting.

See IrradianceMaskPass for further details.

Source

import { EffectComposer } from '@react-three/postprocessing'
import { Atmosphere, IrradianceMask } from '@takram/three-atmosphere/r3f'
import { Layers } from 'three'

const IRRADIANCE_MASK_LAYER = 10
const layers = new Layers()
layers.enable(IRRADIANCE_MASK_LAYER)

const Scene = () => {
  return (
    <Atmosphere>
      <mesh>
        {/* This mesh is included in the mask. */}
        <meshBasicMaterial />
      </mesh>
      <mesh layers={layers}>
        {/* This mesh is masked out. */}
        <meshPhysicalMaterial />
      </mesh>
      <EffectComposer>
        <IrradianceMask selectionLayer={IRRADIANCE_MASK_LAYER} />
      </EffectComposer>
    </Atmosphere>
  )
}

Props

The parameters of IrradianceMaskPass are exposed as props.

AtmosphereMaterialBase

The base class of SkyMaterial and StarsMaterial.

Source

Parameters

irradianceTexture, scatteringTexture, transmittanceTexture

irradianceTexture: DataTexture | null = null
scatteringTexture: Data3DTexture | null = null
transmittanceTexture: DataTexture | null = null

The precomputed textures.

ellipsoid

ellipsoid: Ellipsoid = Ellipsoid.WGS84

See ellipsoid.

ellipsoidCenter, ellipsoidMatrix

ellipsoidCenter: Vector3
ellipsoidMatrix: Matrix4

See ellipsoidCenter, ellipsoidMatrix.

correctAltitude

correctAltitude: boolean = true

See correctAltitude.

photometric

photometric: boolean = true

See photometric.

sunDirection

sunDirection: Vector3 = new Vector3()

The normalized direction to the sun in ECEF coordinates.

sunAngularRadius

sunAngularRadius: number = 0.004675

The angular radius of the sun, in radians.

Increase this value if the sun flickers in a low-resolution environment map. Modifying this value does not affect the sky’s total radiance unless the sun is partially visible.

sunAngularRadius = 0.004675 sunAngularRadius = 0.1

SkyMaterial

A material for displaying the sky. Apply this to a screen quad.

Despite its name, this material renders the atmosphere itself, along with the sun and moon. When viewed from within the atmosphere, it appears as the sky. From space, it represents Earth’s atmosphere with a flat ground.

Source

const material = new SkyMaterial()
getSunDirectionECEF(/* date */, material.sunDirection)
const sky = new Mesh(new PlaneGeometry(2, 2), material)
sky.frustumCulled = false
scene.add(sky)

Parameters

Extends AtmosphereMaterialBase.

sun, moon

sun: boolean = true
moon: boolean = true

Whether to display the sun and moon.

moonDirection

moonDirection: Vector3 = new Vector()

The normalized direction to the moon in ECEF coordinates.

moonAngularRadius

moonAngularRadius: number = 0.0045

The angular radius of the moon, in radians.

lunarRadianceScale

lunarRadianceScale: number = 1

A scaling factor to adjust the brightness of the moon.

lunarRadianceScale = 1 lunarRadianceScale = 5

groundAlbedo

groundAlbedo: Color = new Color()

The albedo of the ground. Defaults to 0.

StarsMaterial

Represents the brightest stars as points at an infinite distance.

The provided data (stars.bin) contains the J2000 ECI directions, magnitudes and black body chromaticities of the 9,096 stars listed in Yale Bright Star Catalog version 5.

Source

const data: ArrayBuffer = /* Load stars.bin */
const material = new StarsMaterial({
  irradianceTexture,
  scatteringTexture,
  transmittanceTexture
})
getSunDirectionECEF(/* date */, material.sunDirection)
const stars = new Points(new StarsGeometry(data), material)
stars.setRotationFromMatrix(getECIToECEFRotationMatrix(/* date */))
scene.add(stars)

Parameters

Extends AtmosphereMaterialBase.

pointSize

pointSize: number = 1

The size of each star, in points.

radianceScale

radianceScale: number = 1

A scaling factor to adjust the brightness of the stars.

background

background: boolean = true

Whether to display the stars at an infinite distance, otherwise, they appear on a unit sphere.

SkyLightProbe

A light probe for indirect sky irradiance.

It calculates spherical harmonics of sky irradiance at its position by sampling the precomputed irradiance texture on the CPU.

Source

const skyLight = new SkyLightProbe({ irradianceTexture })
skyLight.position.set(/* ECEF coordinate in meters */)
getSunDirectionECEF(/* date */, skyLight.sunDirection)
scene.add(skyLight)

skyLight.update()

Parameters

Extends LightProbe

irradianceTexture

irradianceTexture: DataTexture | null = null

The precomputed irradiance texture.

ellipsoid

ellipsoid: Ellipsoid = Ellipsoid.WGS84

See ellipsoid.

ellipsoidCenter, ellipsoidMatrix

ellipsoidCenter: Vector3
ellipsoidMatrix: Matrix4

See ellipsoidCenter, ellipsoidMatrix.

correctAltitude

correctAltitude: boolean = true

See correctAltitude

photometric

photometric: boolean = true

See photometric.

sunDirection

sunDirection: Vector3 = new Vector3()

See sunDirection.

SunDirectionalLight

A directional light representing the sun.

It calculates the sun’s radiance by sampling the precomputed transmittance texture on the CPU.

Source

const sunLight = new SunDirectionalLight({ transmittanceTexture })
sunLight.target.position.set(/* ECEF coordinate in meters */)
getSunDirectionECEF(/* date */, sunLight.sunDirection)
scene.add(sunLight)
scene.add(sunLight.target)

sunLight.update()

Parameters

Extends DirectionalLight

transmittanceTexture

transmittanceTexture: DataTexture | null = null

The precomputed transmittance texture.

ellipsoid

ellipsoid: Ellipsoid = Ellipsoid.WGS84

See ellipsoid.

ellipsoidCenter, ellipsoidMatrix

ellipsoidCenter: Vector3
ellipsoidMatrix: Matrix4

See ellipsoidCenter, ellipsoidMatrix.

correctAltitude

correctAltitude: boolean = true

See correctAltitude

photometric

photometric: boolean = true

See photometric.

sunDirection

sunDirection: Vector3 = new Vector3()

See sunDirection.

Note it's the direction to the sun, not that of light.

distance

distance: number = 1

The distance from the target. Adjust this value if shadows are enabled for the light, as it may need to cover the entire scene.

AerialPerspectiveEffect

A post-processing effect that renders atmospheric transparency and inscattered light. It can optionally render sun and sky irradiance as post-process lighting.

This is for use with the postprocessing’s EffectComposer and is not compatible with the one in Three.js examples.

Source

const aerialPerspective = new AerialPerspectiveEffect(camera, {
  irradianceTexture,
  scatteringTexture,
  transmittanceTexture
})
getSunDirectionECEF(/* date */, aerialPerspective.sunDirection)

const composer = new EffectComposer(renderer, {
  frameBufferType: HalfFloatType
})
composer.addPass(new RenderPass(scene, camera))
composer.addPass(
  new EffectPass(
    camera,
    aerialPerspective,
    new ToneMappingEffect({ mode: ToneMappingMode.AGX })
  )
)

Parameters

Extends postprocessing’s Effect.

normalBuffer

normalBuffer: Texture | null = null

The normal buffer used for post-process lighting. It is not required if both sunIrradiance and skyIrradiance are disabled.

EffectComposer’s default normal buffer lacks sufficient precision, causing banding in shaded areas. Using a floating-point normal buffer resolves this issue.

octEncodedNormal

octEncodedNormal: boolean = false

Indicates that the normal is oct-encoded and stored in the first two elements of the normal buffer texels.

reconstructNormal

reconstructNormal: boolean = false

Whether to reconstruct normals from depth buffer.

irradianceTexture, scatteringTexture, transmittanceTexture

irradianceTexture: DataTexture | null = null
scatteringTexture: Data3DTexture | null = null
transmittanceTexture: DataTexture | null = null

The precomputed textures.

ellipsoid

ellipsoid: Ellipsoid = Ellipsoid.WGS84

See ellipsoid.

ellipsoidCenter, ellipsoidMatrix

ellipsoidCenter: Vector3
ellipsoidMatrix: Matrix4

See ellipsoidCenter, ellipsoidMatrix.

correctAltitude

correctAltitude: boolean = true

See correctAltitude

correctGeometricError

correctGeometricError: boolean = true

These options corrects lighting artifacts caused by geometric errors in surface tiles. The Earth’s surface normals are gradually morphed to a true sphere.

Disable this option if your scene contains objects that penetrate the atmosphere or are located in space.

correctGeometricError = false correctGeometricError = true

photometric

photometric: boolean = true

See photometric.

sunDirection

sunDirection: Vector3 = new Vector3()

See sunDirection.

sunIrradiance, skyIrradiance

sunIrradiance: boolean = false
skyIrradiance: boolean = false

Whether to apply sun and sky irradiance as post-process lighting.

Enabling one without the other is physically incorrect and should only be done for demonstration purposes.

transmittance, inscatter

transmittance: boolean = true
inscatter: boolean = true

Whether to account for the atmospheric transmittance and inscattered light.

irradianceScale

irradianceScale: number = 1

This value adjusts the color buffer to reduce contrast.

Post-process lighting treats the color buffer as albedo, but textures like those in Google Photorealistic 3D Tiles have baked lighting and shadows, resulting in higher contrast. Adjusting this value helps make it less noticeable.

sky

sky: boolean = false

Whether to render the sky as a post-processing effect. Enabling this may reduce the total number of fragments needed to compute the sky radiance.

In this case, the Sky component is redundant and should be omitted.

sun, moon

sun: boolean = true
moon: boolean = true

See sun, moon.

moonDirection

moonDirection: Vector3 = new Vector()

See moonDirection.

moonAngularRadius

moonAngularRadius: number = 0.0045

See moonAngularRadius.

lunarRadianceScale

lunarRadianceScale: number = 1

See lunarRadianceScale.

IrradianceMaskPass

A post-processing pass that renders a mask for the mixed lighting.

If you can afford using MRT, it is preferable to render this mask in your render pass instead.

Source

const IRRADIANCE_MASK_LAYER = 10
const layers = new Layers()
layers.enable(IRRADIANCE_MASK_LAYER)

const irradianceMask = new IrradianceMaskPass(scene, camera)
irradianceMask.selectionLayers = IRRADIANCE_MASK_LAYER
const aerialPerspective = new AerialPerspectiveEffect(camera, {
  irradianceTexture,
  scatteringTexture,
  transmittanceTexture
})

const composer = new EffectComposer(renderer, {
  frameBufferType: HalfFloatType
})
composer.addPass(new RenderPass(scene, camera))
composer.addPass(irradianceMask)
composer.addPass(
  new EffectPass(
    camera,
    aerialPerspective,
    new ToneMappingEffect({ mode: ToneMappingMode.AGX })
  )
)

Parameters

selectionLayer

selectionLayer: number = /* The next unique layer on creation */

Specifies the layer to which the meshes are assigned for rendering to the mask.

inverted

inverted: boolean = false

By default, meshes with the selection layer are masked out from the post-process lighting. Set this to true when rendering the objects for the post-process lighting is less expensive (generally, fewer triangles) than that for the light-source lighting, and configure the layers accordingly.

Functions

getSunDirectionECEF, getMoonDirectionECEF

function getSunDirectionECEF(date: number | Date, result?: Vector3): Vector3
function getMoonDirectionECEF(date: number | Date, result?: Vector3): Vector3

Obtains the direction to the sun and moon in ECEF coordinates for the specified UTC time. This internally uses astronomy-engine and it approximates UTC as being equivalent to UT1.

Source

getECIToECEFRotationMatrix

function getECIToECEFRotationMatrix(
  date: number | Date,
  result?: Matrix4
): Matrix4

Obtains the rotation matrix to convert coordinates from J2000 ECI to ECEF. This internally uses astronomy-engine and it approximates UTC as being equivalent to UT1.

Source

getSunLightColor

interface SunLightColorOptions {
  ellipsoid?: Ellipsoid
  correctAltitude?: boolean
  photometric?: boolean
}

function getSunLightColor(
  transmittanceTexture: DataTexture,
  worldPosition: Vector3,
  sunDirection: Vector3,
  result?: Color,
  options?: SunLightColorOptions
): Color

Calculates the radiance of sunlight observed from a given position by sampling the precomputed transmittance texture on the CPU.

Source

License

MIT

changelog

Changelog

[0.12.0] - 2025-06-12

Changed

  • Added support for the irradiance mask, #30.
  • Removed the use of forwardRef and added it in props.

Fixed

  • AerialPerspectiveEffect: Fixed artifacts in transmittance and inscattered light for the points above the top atmosphere boundary.
  • Fixed the flashing artifacts that appear on surfaces shading the sun, #47.

[0.11.2] - 2025-05-23

Fixed

  • Sky: groundAlbedo prop now resets to default value when removed.
  • Removed process.env.NODE_ENV from the ES build output.

[0.11.1] - 2025-03-14

Fixed

  • Fixed artifacts due to insufficient precision of linear interpolation, #41.

[0.11.0] - 2025-03-09

Updated peer dependencies to React 19 and R3F v9. For React 18 and R3F v8, use version 0.10.x, which will continue to receive fixes.

Changed

  • Migrated types and internal fields to R3F v9.
  • Removed deprecated classes and properties.

[0.10.2] - 2025-03-09

Fixed

  • SkyLight, SunLight: Fixed props not rolling back when unset.

[0.10.1] - 2025-03-09

Compatibility release to continue support for React 18 and R3F v8.

[0.10.0] - 2025-03-02

Changed

  • Added OpenEXR precomputed textures and made them default, #32.
  • Updated binary precomputed textures to use half-float.
  • Deprecated useHalfFloat, as it is now always true.
  • Updated dependencies.

[0.9.0] - 2025-02-23

Changed

  • Switched transpiler to Babel to support property decorators.
  • Updated prop types to use interfaces.
  • Refactored GLSL macro properties using decorators.
  • AerialPerspectiveEffect: Changed PCF filter for BSM to IGN + Vogel disk and reduced default sample count.

Fixed

  • Moved type-fest to dependencies.

[0.8.0] - 2025-02-12

Changed

  • Atmosphere, useAtmosphereTextureProps: Precomputed textures will now be loaded directly from GitHub if textures prop is left undefined.
  • Stars: Data will now be loaded directly from GitHub if data prop is left undefined.
  • Improved safety of number conversion to GLSL macros.
  • Removed shadow length hack near the horizon.
  • Renamed AtmosphereTransientProps type to AtmosphereTransientStates.
  • Updated undocumented functions for preparing cloud and light shafts compositing.
  • Updated dependencies.

Fixed

  • SkyMaterial: Fixed changes to groundAlbedo didn’t trigger shader recompilation.
  • Atmosphere: STBN texture is now loaded only when necessary.
  • Removed dependency on jotai.
  • Fixed type error related to Event.

[0.7.1] - 2025-02-11

Fixed

  • Fixed incorrect precomputed scattering textures, #33.

[0.7.0] - 2025-02-02

Added

  • SkyMaterial: Added support for custom ground albedo in sky rendering (undocumented for now).
  • AerialPerspectiveEffect: Refined R3F type definitions.
  • Added uniform type definitions.
  • Added undocumented functions for preparing cloud and light shafts compositing.

Changed

  • Switched to Vite’s native raw loading function for importing GLSL shaders.
  • Separated shader code exports in @takram/three-atmosphere/shaders.
  • Removed unused shader codes in atmosphere functions.
  • Updated dependencies.

Fixed

  • StarsMaterial: Fixed incorrect proxy to magnitudeRange uniform.
  • StarsMaterial: Ensured stars are not rendered in front of the ground.

[0.6.0] - 2025-01-19

Added

  • Added function to move the ellipsoid via ellipsoidCenter and ellipsoidMatrix, #11.

Changed

  • Updated dependencies.

[0.5.0] - 2024-12-19

Added

  • AerialPerspectiveEffect: Added sky option to render the sky in post-processing.

Changed

  • Sky, Stars: Render after scene objects to take advantage of early Z rejection, #27.
  • Updated dependencies.

Fixed

  • Fixed handling of negative square root calculations, #26.

[0.4.0] - 2024-12-15

Changed

  • AerialPerspectiveEffect: Refined the geometric error correction to support different FoVs and orthographic camera, #21.
  • AerialPerspectiveEffect: Removed geometricErrorAltitudeRange parameter, #21.
  • SkyMaterial: Disabled sun and moon fragment output when using orthographic camera.
  • Stars, StarsMaterial: Disabled when using orthographic camera.

Fixed

  • AerialPerspectiveEffect: Fixed the shading was not visible due to the geometric error correction, #21.

[0.3.0] - 2024-12-11

Added

  • Added support for orthographic camera, #15.

[0.2.0] - 2024-12-10

Changed

  • Made AerialPerspectiveEffect’s camera parameter optional, #18.
  • Changed Stars so it doesn’t render until the data is loaded, #16.

[0.1.0] - 2024-12-06

Changed

  • Added date prop, #10.
  • Added workaround for the viewpoint located underground, #5.

Fixed

  • Removed unused dependency.

[0.0.2] - 2024-12-03

Note this version should have been 0.1.0.

Changed

  • Added sourcemaps, #6.
  • Removed redundant precomputed textures, #9.
  • Reduced bundle size.

Fixed

  • Fixed handling of non-logarithmic depth buffer, #3.
  • Fixed incorrect ECI to ECEF transformation.
  • Refined type definitions.

[0.0.1] - 2024-11-30

Initial release