| Title: | Generates and Samples Realistic Terrestrial Atmospheres |
|---|---|
| Description: | Generates physically based sky environment maps and radiance samples using the spectral Hosek-Wilkie and Prague atmosphere models. Functions write high-dynamic-range 'OpenEXR' domes in latitude-longitude projections, compute per-direction RGB or 55-channel values, and optionally composite time-accurate star fields and moon phases. Features include automatic sun and moon positioning from date, time and location, support for sea-level and high-altitude observers, wide-spectrum coefficients, and multithreaded C++ acceleration for fast, high-resolution output. For model details, see Hosek and Wilkie (2012) <doi:10.1145/2185520.2185591>, Hosek and Wilkie (2013) <doi:10.1109/MCG.2013.18>, Wilkie et al. (2021) <doi:10.1145/3450626.3459758>, and Vevoda et al. (2022) <doi:10.1111/cgf.14677>. |
| Authors: | Tyler Morgan-Wall [aut, cre, cph], Petr Vevoda [ctb], Charles University [cph], Eric Bruneton [ctb, cph], Lukas Hosek [ctb, cph], Alexander Wilkie [ctb, cph] |
| Maintainer: | Tyler Morgan-Wall <[email protected]> |
| License: | GPL-3 |
| Version: | 0.3.2 |
| Built: | 2026-06-27 11:31:33 UTC |
| Source: | https://github.com/cran/skymodelr |
Evaluate the Prague spectral sky model at arbitrary spherical
directions and return radiance at a user-specified wavelength. Use
render_mode = "all" for atmosphere + solar disk, "atmosphere" for
atmospheric radiance only, or "sun" for the solar disk only.
calculate_sky_radiance( phi, theta, lambda_nm, altitude = 0, elevation = 10, visibility = 50, albedo = 0.5, azimuth = 90, number_cores = 1, wide_spectrum = FALSE, render_mode = "all" )calculate_sky_radiance( phi, theta, lambda_nm, altitude = 0, elevation = 10, visibility = 50, albedo = 0.5, azimuth = 90, number_cores = 1, wide_spectrum = FALSE, render_mode = "all" )
phi |
Azimuthal angle of the sample, degrees. Vectorized. Range 0 to 360. |
theta |
Vertical angle of the sample, degrees. Vectorized. Range -90 to 90. |
lambda_nm |
Wavelength in nanometers. Vectorized. Must lie within the loaded Prague dataset range. |
altitude |
Default |
elevation |
Default |
visibility |
Default |
albedo |
Default |
azimuth |
Default |
number_cores |
Default |
wide_spectrum |
Default |
render_mode |
Default |
Numeric vector of radiance values at the requested wavelength(s).
lambda_vals = calculate_sky_radiance( phi = c(90, 90), theta = c(45, 45), lambda_nm = 550, altitude = c(0, 10000), elevation = 20, visibility = 80, albedo = 0.1 ) cbind(altitude = c(0, 10000), radiance = lambda_vals)lambda_vals = calculate_sky_radiance( phi = c(90, 90), theta = c(45, 45), lambda_nm = 550, altitude = c(0, 10000), elevation = 20, visibility = 80, albedo = 0.1 ) cbind(altitude = c(0, 10000), radiance = lambda_vals)
Evaluate the Prague spectral sky model at arbitrary spherical directions without writing an image, returning radiance-only samples.
calculate_sky_values( phi, theta, altitude = 0, elevation = 10, visibility = 50, albedo = 0.5, azimuth = 90, number_cores = 1, wide_spectrum = FALSE, render_mode = "all" )calculate_sky_values( phi, theta, altitude = 0, elevation = 10, visibility = 50, albedo = 0.5, azimuth = 90, number_cores = 1, wide_spectrum = FALSE, render_mode = "all" )
phi |
Horizontal angle of the sample, degrees. Vectorized. Range 0 to 360. |
theta |
Vertical angle of the sample, degrees. Vectorized. Range -90 to 90. |
altitude |
Default |
elevation |
Default |
visibility |
Default |
albedo |
Default |
azimuth |
Default |
number_cores |
Default |
wide_spectrum |
Default |
render_mode |
Default |
3-column RGB matrix.
# Generate a basic atmosphere with the Prague model value_grid = expand.grid( phi = seq(0, 360, by = 30), theta = seq(0, 90, by = 10), altitude = c(0, 10000) ) vals = calculate_sky_values( phi = value_grid$phi, theta = value_grid$theta, altitude = value_grid$altitude, elevation = 45, visibility = 120, albedo = 0 ) cbind(value_grid, vals)# Generate a basic atmosphere with the Prague model value_grid = expand.grid( phi = seq(0, 360, by = 30), theta = seq(0, 90, by = 10), altitude = c(0, 10000) ) vals = calculate_sky_values( phi = value_grid$phi, theta = value_grid$theta, altitude = value_grid$altitude, elevation = 45, visibility = 120, albedo = 0 ) cbind(value_grid, vals)
Evaluate the Prague or Hosek sky model at the sun center and integrate against the CIE Y curve to return a luminance value. This is useful for relative attenuation (e.g., comparing zenith sun to a low sun).
calculate_sun_brightness( elevation = 10, azimuth = 90, albedo = 0.5, turbidity = 3, altitude = 0, visibility = 50, hosek = TRUE, wide_spectrum = FALSE, lambda_nm = NULL )calculate_sun_brightness( elevation = 10, azimuth = 90, albedo = 0.5, turbidity = 3, altitude = 0, visibility = 50, hosek = TRUE, wide_spectrum = FALSE, lambda_nm = NULL )
elevation |
Default |
azimuth |
Default |
albedo |
Default |
turbidity |
Default |
altitude |
Default |
visibility |
Default |
hosek |
Default |
wide_spectrum |
Default |
lambda_nm |
Optional vector of wavelengths for Hosek sampling. |
Numeric scalar of sun luminance (CIE Y, relative scale).
calculate_sun_brightness(elevation = 45, hosek = TRUE)calculate_sun_brightness(elevation = 45, hosek = TRUE)
Removes files cached by download_sky_data() under
tools::R_user_dir("skymodelr", "data").
clear_sky_data(files = NULL, ask = interactive())clear_sky_data(files = NULL, ask = interactive())
files |
Default |
ask |
Default |
Invisibly, the paths successfully removed.
clear_sky_data()clear_sky_data()
This model which allows for sun angles below the horizon, wide spectral ranges including infrared, polarization, as well rendering at altitude) need to download a coefficient file. There are three versions of this dataset, listed here in order of increasing size:
download_sky_data(sea_level = TRUE, wide_spectrum = FALSE)download_sky_data(sea_level = TRUE, wide_spectrum = FALSE)
sea_level |
Default |
wide_spectrum |
Default |
| Argument combination | File | Size |
sea_level = TRUE, wide_spectrum = FALSE |
SkyModelDatasetGround.dat |
107MB |
sea_level = TRUE, wide_spectrum = TRUE |
PragueSkyModelDatasetGroundInfra.dat |
574MB |
sea_level = FALSE |
SkyModelDataset.dat |
2.4GB |
Invisibly, the full path to the data file.
# Standard (11-channel, sea-level) coefficients download_sky_data() # Wide-spectrum sea-level coefficients download_sky_data(wide_spectrum = TRUE) # Full altitude-range coefficients download_sky_data(sea_level = FALSE)# Standard (11-channel, sea-level) coefficients download_sky_data() # Wide-spectrum sea-level coefficients download_sky_data(wide_spectrum = TRUE) # Full altitude-range coefficients download_sky_data(sea_level = FALSE)
Note that this is just a scaled version of generate_sky(), scaled down by the luminance
of the moon as compared to the sun. This function takes the phase of the moon into account,
along with the increase in luminosity around a full moon (known as opposition surge). Moonlight
attenuation uses the Rozenberg/Krisciunas-Schaefer airmass approximation with configurable moon_extinction_kV.
generate_moon_latlong( datetime, lat, lon, filename = NA, albedo = 0.5, turbidity = 3, altitude = 0, resolution = 2048, number_cores = 1, moon_atmosphere = FALSE, earthshine = TRUE, earthshine_albedo = 0.19, solar_irradiance_w_m2 = 1300, moon_extinction_kV = 0.172, hosek = TRUE, wide_spectrum = FALSE, visibility = 50, moon_texture_width = 801, moon_texture_height = 801, verbose = FALSE )generate_moon_latlong( datetime, lat, lon, filename = NA, albedo = 0.5, turbidity = 3, altitude = 0, resolution = 2048, number_cores = 1, moon_atmosphere = FALSE, earthshine = TRUE, earthshine_albedo = 0.19, solar_irradiance_w_m2 = 1300, moon_extinction_kV = 0.172, hosek = TRUE, wide_spectrum = FALSE, visibility = 50, moon_texture_width = 801, moon_texture_height = 801, verbose = FALSE )
datetime |
POSIX-compatible date-time. |
lat |
Observer latitude (degrees N). |
lon |
Observer longitude (degrees E; west < 0). |
filename |
Default |
albedo |
Default |
turbidity |
Default |
altitude |
Default |
resolution |
Default |
number_cores |
Default |
moon_atmosphere |
Default |
earthshine |
Default |
earthshine_albedo |
Default |
solar_irradiance_w_m2 |
Default |
moon_extinction_kV |
Default |
hosek |
Default |
wide_spectrum |
Default |
visibility |
Default |
moon_texture_width |
Default |
moon_texture_height |
Default |
verbose |
Default |
Either the image array, or the array is invisibly returned if a file
is written. The array has dimensions (resolution, 2 * resolution, 4).
Writing to non-EXR formats will introduce precision loss because HDR data are quantised to the destination format, and low dynamic range outputs like PNG and JPEG files will not represent the true luminosity values encoded in the array.
# Moonlit sky (Hosek), mid-evening in DC generate_moon_latlong( datetime = as.POSIXct("2025-09-05 19:30:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, resolution = 400, turbidity = 3, verbose = TRUE ) |> rayimage::render_exposure(15) |> rayimage::plot_image()# Moonlit sky (Hosek), mid-evening in DC generate_moon_latlong( datetime = as.POSIXct("2025-09-05 19:30:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, resolution = 400, turbidity = 3, verbose = TRUE ) |> rayimage::render_exposure(15) |> rayimage::plot_image()
Build a planetary luminance map aligned with the sky dome for
compositing within generate_sky_latlong().
generate_planets( datetime, lon, lat, filename = NA, resolution = 2048, turbidity = 3, ozone_du = 300, altitude = 0, color = FALSE, planet_width = 1, upper_hemisphere_only = TRUE, atmosphere_effects = TRUE, number_cores = 1, verbose = FALSE )generate_planets( datetime, lon, lat, filename = NA, resolution = 2048, turbidity = 3, ozone_du = 300, altitude = 0, color = FALSE, planet_width = 1, upper_hemisphere_only = TRUE, atmosphere_effects = TRUE, number_cores = 1, verbose = FALSE )
datetime |
POSIXct timestamp used for ephemerides. |
lon |
Observer longitude in degrees (east positive). |
lat |
Observer latitude in degrees. |
filename |
Default |
resolution |
Default |
turbidity |
Atmospheric turbidity for extinction modelling. |
ozone_du |
Column ozone (Dobson Units) for colour shifts. |
altitude |
Observer altitude in metres. |
color |
Render RGB ( |
planet_width |
Approximate point-spread size for planets in pixels. |
upper_hemisphere_only |
If |
atmosphere_effects |
If |
number_cores |
CPU threads used for rendering. |
verbose |
Emit diagnostic output when |
Either the image array, or the array is invisibly returned if a file
is written. The array has dimensions (resolution, 2 * resolution, 4).
Writing to non-EXR formats will introduce precision loss because HDR data are quantised to the destination format, and low dynamic range outputs like PNG and JPEG files will not represent the true luminosity values encoded in the array.
# Basic star field over Washington, DC at a fixed time generate_planets( datetime = as.POSIXct("2025-03-21 02:20:00", tz = "America/New_York"), lon = -77.0369, lat = 38.9072, resolution = 400, color = TRUE, planet_width = 1, atmosphere_effects = TRUE, upper_hemisphere_only = TRUE, number_cores = 2 ) |> rayimage::plot_image()# Basic star field over Washington, DC at a fixed time generate_planets( datetime = as.POSIXct("2025-03-21 02:20:00", tz = "America/New_York"), lon = -77.0369, lat = 38.9072, resolution = 400, color = TRUE, planet_width = 1, atmosphere_effects = TRUE, upper_hemisphere_only = TRUE, number_cores = 2 ) |> rayimage::plot_image()
Evaluate either the Hosek-Wilkie or Prague analytic sky models
and return a high-dynamic-range image array for the given solar
configuration. An image file is written only when filename is supplied.
generate_sky( filename = NA, albedo = 0.1, turbidity = 3, elevation = 10, azimuth = 90, altitude = 0, resolution = 2048, number_cores = 1, hosek = TRUE, wide_spectrum = FALSE, visibility = 50, verbose = FALSE, render_mode = "all", below_horizon = TRUE )generate_sky( filename = NA, albedo = 0.1, turbidity = 3, elevation = 10, azimuth = 90, altitude = 0, resolution = 2048, number_cores = 1, hosek = TRUE, wide_spectrum = FALSE, visibility = 50, verbose = FALSE, render_mode = "all", below_horizon = TRUE )
filename |
Default |
albedo |
Default |
turbidity |
Default |
elevation |
Default |
azimuth |
Default |
altitude |
Default |
resolution |
Default |
number_cores |
Default |
hosek |
Default |
wide_spectrum |
Default |
visibility |
Default |
verbose |
Default |
render_mode |
Default |
below_horizon |
Default |
Either the image array, or the array is invisibly returned if a file
is written. The array has dimensions (resolution, 2 * resolution, 4).
Writing to non-EXR formats will introduce precision loss because HDR data are quantised to the destination format, and low dynamic range outputs like PNG and JPEG files will not represent the true luminosity values encoded in the array.
sky = generate_sky( resolution = 8, elevation = 30, azimuth = 135, render_mode = "atmosphere" ) dim(sky) # Hosek model (default): clear morning, Sun SE, with solar disk generate_sky( resolution = 400, elevation = 15, azimuth = 135, turbidity = 3, render_mode = "all" ) |> rayimage::plot_image() # Same view but hazier and without the solar disk generate_sky( resolution = 400, elevation = 15, azimuth = 135, turbidity = 6, render_mode = "atmosphere" ) |> rayimage::plot_image() # Prague model (requires downloaded coefficients) generate_sky( resolution = 400, hosek = FALSE, altitude = 0, visibility = 80, albedo = 0.2, elevation = 5, azimuth = 220, number_cores = 2 ) |> rayimage::plot_image()sky = generate_sky( resolution = 8, elevation = 30, azimuth = 135, render_mode = "atmosphere" ) dim(sky) # Hosek model (default): clear morning, Sun SE, with solar disk generate_sky( resolution = 400, elevation = 15, azimuth = 135, turbidity = 3, render_mode = "all" ) |> rayimage::plot_image() # Same view but hazier and without the solar disk generate_sky( resolution = 400, elevation = 15, azimuth = 135, turbidity = 6, render_mode = "atmosphere" ) |> rayimage::plot_image() # Prague model (requires downloaded coefficients) generate_sky( resolution = 400, hosek = FALSE, altitude = 0, visibility = 80, albedo = 0.2, elevation = 5, azimuth = 220, number_cores = 2 ) |> rayimage::plot_image()
Convenience wrapper around generate_sky() that:
Computes the Sun's apparent position for datetime, lat, and lon
(via Swiss Ephemeris / swephR).
Renders the corresponding sky model.
Optionally overlays a star field using generate_stars() or moon with generate_moon_latlong().
generate_sky_latlong( datetime, lat, lon, filename = NA, albedo = 0.5, turbidity = 3, altitude = 0, resolution = 2048, number_cores = 1, hosek = TRUE, wide_spectrum = FALSE, visibility = 50, stars = FALSE, star_width = 1, planets = FALSE, moon = FALSE, moon_atmosphere = FALSE, moon_hosek = TRUE, render_mode = "all", below_horizon = TRUE, verbose = FALSE, stars_exposure = 0, ... )generate_sky_latlong( datetime, lat, lon, filename = NA, albedo = 0.5, turbidity = 3, altitude = 0, resolution = 2048, number_cores = 1, hosek = TRUE, wide_spectrum = FALSE, visibility = 50, stars = FALSE, star_width = 1, planets = FALSE, moon = FALSE, moon_atmosphere = FALSE, moon_hosek = TRUE, render_mode = "all", below_horizon = TRUE, verbose = FALSE, stars_exposure = 0, ... )
datetime |
POSIX-compatible date-time. |
lat |
Observer latitude (degrees N). |
lon |
Observer longitude (degrees E; west < 0). |
filename |
Default |
albedo |
Default |
turbidity |
Default |
altitude |
Default |
resolution |
Default |
number_cores |
Default |
hosek |
Default |
wide_spectrum |
Default |
visibility |
Default |
stars |
Default |
star_width |
Default |
planets |
Default |
moon |
Default |
moon_atmosphere |
Default |
moon_hosek |
Default |
render_mode |
Default |
below_horizon |
Default |
verbose |
Default |
stars_exposure |
Default |
... |
Additional named arguments forwarded to |
Solar angles - altitude (degrees above the horizon) and azimuth (degrees clockwise from east, so 90 degrees = south) - are derived internally; you never have to supply them directly.
Black-sky rule - With the Prague model the sky radiance is defined only
down to -4.2 degrees, and with the Hosek model it is defined only about 0 degrees.
Below that the function skips the sky render and writes only stars when stars = TRUE.
Either the raw data, or the data is invisibly returned if filename is given. The EXR is written to filename.
sky = generate_sky_latlong( datetime = as.POSIXct("2025-03-21 12:00:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, resolution = 8 ) dim(sky) # Morning sunrise on spring solstice over Washington, DC with Prague model generate_sky_latlong( datetime = as.POSIXct("2025-03-21 06:15:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2, hosek = FALSE ) |> rayimage::plot_image() generate_sky_latlong( datetime = as.POSIXct("2025-03-21 12:00:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2 ) |> rayimage::plot_image() generate_sky_latlong( datetime = as.POSIXct("2025-03-21 18:00:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2 ) |> rayimage::plot_image() generate_sky_latlong( datetime = as.POSIXct("2025-03-21 18:30:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2, hosek = FALSE, verbose = TRUE ) |> rayimage::render_exposure(exposure = 2) |> rayimage::plot_image()sky = generate_sky_latlong( datetime = as.POSIXct("2025-03-21 12:00:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, resolution = 8 ) dim(sky) # Morning sunrise on spring solstice over Washington, DC with Prague model generate_sky_latlong( datetime = as.POSIXct("2025-03-21 06:15:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2, hosek = FALSE ) |> rayimage::plot_image() generate_sky_latlong( datetime = as.POSIXct("2025-03-21 12:00:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2 ) |> rayimage::plot_image() generate_sky_latlong( datetime = as.POSIXct("2025-03-21 18:00:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2 ) |> rayimage::plot_image() generate_sky_latlong( datetime = as.POSIXct("2025-03-21 18:30:00", tz = "America/New_York"), lat = 38.9072, lon = -77.0369, number_cores = 2, hosek = FALSE, verbose = TRUE ) |> rayimage::render_exposure(exposure = 2) |> rayimage::plot_image()
generate_sky()
Render a star map for a given observer location, time, and atmospheric
conditions so it can be composited with generate_sky(). Returns a
(resolution, 2 * resolution, 4) array with an opaque alpha channel. An
image file is written only when filename is supplied.
generate_stars( lon, lat, datetime, filename = NA, resolution = 2048, turbidity = 3, ozone_du = 300, altitude = 0, color = TRUE, star_width = 1, upper_hemisphere_only = TRUE, atmosphere_effects = TRUE, number_cores = 1 )generate_stars( lon, lat, datetime, filename = NA, resolution = 2048, turbidity = 3, ozone_du = 300, altitude = 0, color = TRUE, star_width = 1, upper_hemisphere_only = TRUE, atmosphere_effects = TRUE, number_cores = 1 )
lon |
Observer longitude in degrees (east positive). |
lat |
Observer latitude in degrees. |
datetime |
|
filename |
Default |
resolution |
Default |
turbidity |
Default |
ozone_du |
Default |
altitude |
Default |
color |
Default |
star_width |
Default |
upper_hemisphere_only |
Default |
atmosphere_effects |
Default |
number_cores |
Default |
Either the image array, or the array is invisibly returned if a file
is written. The array has dimensions (resolution, 2 * resolution, 4).
Writing to non-EXR formats will introduce precision loss because HDR data are quantised to the destination format, and low dynamic range outputs like PNG and JPEG files will not represent the true luminosity values encoded in the array.
star_map = generate_stars( resolution = 8, lon = -77.0369, lat = 38.9072, datetime = as.POSIXct("2025-03-21 02:20:00", tz = "UTC"), atmosphere_effects = FALSE, number_cores = 1 ) dim(star_map) # Note: exposure has been increased for all examples (via white_point) for # ease of visibility in documentation # Basic star field over Washington, DC at a fixed time generate_stars( resolution = 400, lon = -77.0369, lat = 38.9072, datetime = as.POSIXct("2025-03-21 02:20:00", tz = "America/New_York"), color = TRUE, star_width = 1, atmosphere_effects = TRUE, upper_hemisphere_only = TRUE, number_cores = 2 ) |> rayimage::plot_image() # Monochrome stars, no atmospheric extinction/reddening, full sphere generate_stars( resolution = 400, lon = -122.4194, lat = 37.7749, datetime = as.POSIXct("2025-06-01 08:00:00", tz = "UTC"), color = FALSE, star_width = 1, upper_hemisphere_only = FALSE, atmosphere_effects = FALSE ) |> rayimage::plot_image() # Sharper stars (smaller PSF) with ozone/turbidity and altitude generate_stars( resolution = 400, lon = 10, lat = 45, datetime = as.POSIXct("2025-12-01 22:00:00", tz = "UTC"), star_width = 0.5, turbidity = 3.5, ozone_du = 320, altitude = 1000, color = TRUE ) |> rayimage::plot_image()star_map = generate_stars( resolution = 8, lon = -77.0369, lat = 38.9072, datetime = as.POSIXct("2025-03-21 02:20:00", tz = "UTC"), atmosphere_effects = FALSE, number_cores = 1 ) dim(star_map) # Note: exposure has been increased for all examples (via white_point) for # ease of visibility in documentation # Basic star field over Washington, DC at a fixed time generate_stars( resolution = 400, lon = -77.0369, lat = 38.9072, datetime = as.POSIXct("2025-03-21 02:20:00", tz = "America/New_York"), color = TRUE, star_width = 1, atmosphere_effects = TRUE, upper_hemisphere_only = TRUE, number_cores = 2 ) |> rayimage::plot_image() # Monochrome stars, no atmospheric extinction/reddening, full sphere generate_stars( resolution = 400, lon = -122.4194, lat = 37.7749, datetime = as.POSIXct("2025-06-01 08:00:00", tz = "UTC"), color = FALSE, star_width = 1, upper_hemisphere_only = FALSE, atmosphere_effects = FALSE ) |> rayimage::plot_image() # Sharper stars (smaller PSF) with ozone/turbidity and altitude generate_stars( resolution = 400, lon = 10, lat = 45, datetime = as.POSIXct("2025-12-01 22:00:00", tz = "UTC"), star_width = 0.5, turbidity = 3.5, ozone_du = 320, altitude = 1000, color = TRUE ) |> rayimage::plot_image()
Lists files cached by download_sky_data() under
tools::R_user_dir("skymodelr", "data").
list_sky_data()list_sky_data()
A data frame with columns file, path, size, and modified.
list_sky_data()list_sky_data()