Skip to content

16 - Illumination and atmosphere

The illumination of a scene has two parts: the sun (less.Sun) gives the direction of the sun and the solar spectrum at the top of the atmosphere; the atmosphere model computes the direct sunlight and diffuse skylight reaching the ground, and some models also compute the atmospheric effects between the ground and the sensor.

import less

scene = less.Scene()
scene.size = 20
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.2))
scene.illumination = less.Illumination(
    source=less.Sun(zenith=30, azimuth=150),
    atmosphere=less.SimpleSpectralAtmosphere(turbidity=2.5),
)

Without a spectrum, Sun uses the built-in top-of-atmosphere solar spectrum. Sun(wavelengths=..., irradiance=...) supplies your own spectrum in W m⁻² nm⁻¹, as irradiance at the top of the atmosphere on a plane perpendicular to the sun's rays.

Choosing an atmosphere model

Model Use Notes
less.Atmosphere Satellite and airborne images, top-of-atmosphere reflectance Layered radiative transfer; computes ground illumination and transmission to the sensor
less.SixSAtmosphere When you work with 6S parameters Requires less3d[atmosphere]
less.PrescribedAtmosphere Known direct and diffuse transmittances Gives the transmittances directly
less.SimpleSpectralAtmosphere Fast broadband simulations Simplified spectral attenuation, isotropic skylight
less.HosekWilkieAtmosphere Visible wavelengths with a realistic sky brightness distribution 320–720 nm
less.NoAtmosphere No atmosphere Sunlight is not attenuated; no skylight

The layered atmosphere Atmosphere

scene.illumination = less.Illumination(
    source=less.Sun(zenith=30, azimuth=150),
    atmosphere=less.Atmosphere.standard(
        "midlatitude_summer",
        aerosol="continental",
        aot550=0.10,
        ground_altitude_km=0.0,
        streams=8,
        sky_mode="anisotropic",
    ),
)

Standard profiles:

Name Typical conditions
"tropical" Tropics
"midlatitude_summer" Mid-latitude summer
"midlatitude_winter" Mid-latitude winter
"subarctic_summer" Subarctic summer
"subarctic_winter" Subarctic winter
"us_standard", "us76" US Standard Atmosphere 1976

Aerosol types are "continental", "maritime", "urban", "desert", "biomass_burning" and "stratospheric". aot550 is the aerosol optical thickness at 550 nm; larger values attenuate direct sunlight more. ground_altitude_km is the elevation of the ground. sky_mode="anisotropic" keeps the directional variation of sky brightness, while "isotropic" treats skylight as the same from all directions.

Custom profiles

profile = less.AtmosphericProfile.standard("us76")
print(profile.surface_pressure(0.0))                       # hPa
print(profile.column("h2o", ground_altitude_km=0.5))

custom = less.Atmosphere(profile=profile, aerosol="maritime", aot550=0.05)

A custom AtmosphericProfile uses heights in km, pressure in hPa, temperature in K and gas number densities in cm⁻³.

Computing the atmosphere on its own

The illumination and transmittances of an atmosphere can be computed without a scene:

import numpy as np

atmosphere = less.Atmosphere.standard("us76", aot550=0.10)
wavelengths = np.arange(400.0, 1001.0, 5.0)
result = atmosphere.solve(wavelengths, sun_zenith=40, output_altitudes_km=[2.0, 8.0, 20.0])

direct = result.direct_normal_irradiance          # direct irradiance at the ground, normal to the rays
diffuse = result.diffuse_horizontal_irradiance    # diffuse sky irradiance on a horizontal surface
up = result.upward_transmittance(view_zenith=10, observer_altitude_km=8.0)
Result Meaning
direct_normal_irradiance Direct irradiance at the ground on a plane perpendicular to the rays
diffuse_horizontal_irradiance Diffuse sky irradiance on a horizontal surface at the ground
direct_transmittance Direct-beam transmittance
upward_transmittance(...) Directional transmittance from the ground up to a given height
path_radiance(...) Atmospheric path radiance in the viewing direction
to_observer(...) Propagates ground radiance up to a given height
directional_sky_radiance(...) Sky radiance by direction

Irradiance is in W m⁻² nm⁻¹ and radiance in W m⁻² sr⁻¹ nm⁻¹.

Images at airborne and satellite altitude

With Atmosphere, optical sensors can return radiance at a given altitude or at the top of the atmosphere:

projection = less.Orthographic(image_size=64, view_zenith=10, view_azimuth=180)

airborne = scene.simulate(less.OpticalImager(
    projection, bands=less.Sentinel2A(), spectral_resolution=20, quality=16,
    observation_altitude_km=8.0))

top_of_atmosphere = scene.simulate(less.OpticalImager(
    projection, bands=less.Sentinel2A(), spectral_resolution=20, quality=16,
    observation_level="toa"))

observation_altitude_km is an altitude above sea level and is independent of the projection's geometric height in the scene. The atmosphere also affects other sensors: fluorescence images include the upward transmittance at the emission wavelengths, thermal images include downwelling longwave radiation and the atmosphere's own emission, and LiDAR includes the two-way attenuation.

6S

pip install "less3d[atmosphere]"
six_s = less.SixSAtmosphere(
    atmosphere_profile="midlatitude_summer",
    aerosol_type="continental",
    aot550=0.1,
    ground_altitude=0.0,
)

Profile names are the same as above; aerosol types are no_aerosols, continental, maritime, urban, desert and biomass_burning. Use it as Illumination(atmosphere=...).

Prescribed transmittances

When the direct and diffuse transmittances of the atmosphere are known:

scene.illumination = less.Illumination(
    source=less.Sun(zenith=40, azimuth=160,
                    wavelengths=[450, 550, 650],
                    irradiance=[1.85, 1.88, 1.55]),
    atmosphere=less.PrescribedAtmosphere(
        wavelengths=[450, 550, 650],
        direct_beam_transmittance=[0.60, 0.70, 0.78],
        diffuse_horizontal_transmittance=[0.20, 0.14, 0.09],
    ),
)

The two coefficients are defined differently:

  • direct_beam_transmittance = direct irradiance at the ground (perpendicular to the rays) / solar irradiance at the top of the atmosphere (perpendicular to the rays);
  • diffuse_horizontal_transmittance = diffuse sky irradiance on a horizontal surface at the ground / top-of-atmosphere solar irradiance on a horizontal surface.

So for a solar zenith angle θ and top-of-atmosphere irradiance E:

direct irradiance at the ground (perpendicular to the rays) = E × direct_beam_transmittance
diffuse irradiance on a horizontal surface                  = E × cos θ × diffuse_horizontal_transmittance

Both coefficients may be numbers or spectral arrays; at each wavelength their sum may not exceed 1.

Simple models

quick = less.SimpleSpectralAtmosphere(turbidity=2.5)   # 300–2500 nm, isotropic sky
visible_sky = less.HosekWilkieAtmosphere(turbidity=2.5)  # visible, sky brightness varies with direction
vacuum = less.NoAtmosphere()

turbidity describes how hazy the atmosphere is: around 2 for a clear sky, 5 or more for a hazy one.

The sky in the thermal infrared

Thermal simulations also need the sky's longwave radiation. less.Atmosphere computes it; NoAtmosphere has none; the other models need the sky's brightness temperature, or microclimate conditions at simulation time:

clear_sky = less.SimpleSpectralAtmosphere(turbidity=2.0, sky_temperature=260.0)  # K

When the energy balance is used, the downwelling longwave radiation in less.Microclimate (estimated from air temperature and humidity if not given) also serves as the thermal sky. See chapter 26.

Next