LESS 3.0
GPU + CPU accelerated 3D radiative transfer model for remote sensing simulation
LESS 3.0 is a complete reimplementation of the LESS model — a widely-used 3D radiative transfer framework in quantitative remote sensing research. Built around NVIDIA OptiX, cross-vendor Vulkan Ray Query, Intel Embree, and a modern Python API, LESS 3.0 inherits the physical foundations of the original LESS while adding hardware acceleration, a redesigned scripting interface, and full physical coupling of energy balance, photosynthesis, and solar-induced chlorophyll fluorescence (SIF).
The original LESS remains available at lessrt.org. LESS 3.0 is the recommended path for new projects.
Key Features
- End-to-end satellite imaging — Pushbroom motion and per-pixel geometry, native atmospheric propagation, spectral response, PSF/MTF, detector noise, ADC quantisation, and geolocation in one simulation chain.
- Three compute backends — OptiX is the high-performance NVIDIA path, Vulkan Ray Query provides experimental cross-vendor GPU coverage, and Embree supplies portable CPU workflows.
- Clean Python API — Designed for remote sensing scientists. Build a scene in 10 lines of code.
- Digital twin architecture — Build the scene once, simulate many times. Update illumination or surface properties without rebuilding geometry.
- Multi-sensor support — Optical, thermal infrared, LiDAR point cloud/waveform, SIF fluorescence, and passive/active microwave sensors.
- Full physical coupling — 3D radiation field → energy balance → photosynthesis → SIF, all tightly coupled to the Monte Carlo ray tracing engine.
- Interactive 3D viewer —
scene.show()opens a browser-based viewer to inspect the scene and preview simulation results.
Installation
pip install less3d
Pre-built wheels for Windows and Linux are provided for Python 3.10–3.13. No compiler, CUDA toolkit, or additional runtime installation required.
| CPU | Cross-vendor GPU | NVIDIA GPU | |
|---|---|---|---|
| Backend | Embree | Vulkan Ray Query | OptiX + CUDA |
| Hardware | Modern x86-64 | Vulkan 1.2 Ray Query GPU | Compatible NVIDIA GPU |
| Memory | System RAM | 4 GB+ VRAM recommended | 8 GB+ VRAM recommended |
| Best use | Portable core workflows | Portability and validation | Production Monte Carlo |
| Python | 3.10–3.13 | 3.10–3.13 | 3.10–3.13 |
Feature coverage differs by backend. Use
less.can_use("feature")orscene.can_use("feature")for the final answer in the current installation.
Backend feature matrix
OK means the workflow is implemented by a non-experimental backend.
Experimental means it is implemented and covered by cross-backend regression
tests, but the Vulkan backend is still being optimized and may be substantially
slower than OptiX. -- means that backend does not implement the workflow.
| User workflow | OptiX + CUDA | Vulkan Ray Query | Embree CPU |
|---|---|---|---|
| Optical imaging | OK | Experimental | OK |
| Thermal-infrared imaging | OK | Experimental | OK |
| Per-primitive thermal temperatures | OK | Experimental | OK |
| SIF imaging | OK | Experimental | OK |
| Directional BRF / albedo | OK | Experimental | OK |
| 3D radiation field / fPAR | OK | Experimental | OK |
| Irradiance maps | OK | Experimental | OK |
| LiDAR point cloud | OK | Experimental | OK |
| Full-waveform LiDAR | OK | Experimental | OK |
| Energy balance | OK | Experimental | OK |
| Per-primitive spectral radiation process | OK | Experimental | OK |
| Photosynthesis process | OK | Experimental | OK |
| SIF process | OK | Experimental | OK |
| Passive microwave brightness temperature | OK | Experimental | OK |
| Active microwave radar backscatter | OK | Experimental | OK |
| Dynamic instance updates | OK | Experimental | OK |
| Periodic / repetitive scenes | OK | Experimental | OK |
| Terrain-following sensing | OK | Experimental | OK |
The table describes code coverage, not the hardware in a particular computer. For the single user-facing answer on the current machine, call for example:
less.can_use("lidar_waveform", backend="vulkan")
scene.can_use("energy_balance")
On NVIDIA hardware, use OptiX for production simulations. Vulkan is currently intended for cross-vendor access, validation, and backend development; it is not yet a performance replacement for the CUDA kernels.
Quick Start
import less
# Create a 10 m × 10 m bare-soil scene
scene = less.Scene()
scene.size = 10.0
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.3))
scene.illumination = less.DirectDiffuse(sun_zenith=30, sun_azimuth=150)
scene.build()
# Simulate a nadir RGB image
image = scene.simulate(less.OpticalImager(
less.Orthographic(image_size=256),
bands=[650, 550, 450], # R, G, B (nm)
quality=128,
))
image.save("output.png")
Thanks to the digital twin architecture, updating scene parameters does not require a rebuild:
# Change sun angle and re-simulate — no rebuild needed
scene.illumination = less.DirectDiffuse(sun_zenith=60, sun_azimuth=90)
image2 = scene.simulate(sensor)
Simulation Capabilities
| Domain | What you can simulate |
|---|---|
| Satellite imaging | Local-track pushbroom acquisition, TOA atmosphere, instrument response, detector DN and per-pixel geolocation |
| Optical | RGB, multispectral, and hyperspectral images; BRF / BRDF angular sampling; NDVI and vegetation indices |
| Thermal infrared | Per-component temperature scenes (sunlit/shaded leaf, soil, trunk); thermal radiance images |
| LiDAR | Airborne laser scanning (ALS) and terrestrial laser scanning (TLS) point clouds and full waveforms |
| Vegetation physiology | 3D PAR radiation field, full energy balance, photosynthesis, solar-induced chlorophyll fluorescence (SIF) imaging |
| Microwave | Passive H/V brightness temperature and active HH/HV/VH/VV radar backscatter, including vegetation and trunk-ground interactions |
Forest Scene Example
import less
import numpy as np
scene = less.Scene()
scene.size = 30.0
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.12))
scene.illumination = less.DirectDiffuse(sun_zenith=35, sun_azimuth=225)
# Broadleaf tree with PROSPECT leaf optical properties
birch = less.Object("birch", mesh="birch.obj")
birch.set_property("leaves", less.Prospect(cab=40, car=8, cw=0.012, cm=0.009, N=1.5))
# Random planting positions
xy = np.random.rand(50, 2) * 30
positions = np.c_[xy, np.zeros(50)]
scene.add(birch, positions=positions)
scene.build()
# Multispectral image (green, red, NIR)
image = scene.simulate(less.OpticalImager(
less.Orthographic(image_size=512),
bands=[550, 670, 800],
quality=256,
))
image.save("forest.tif") # GeoTIFF preserves physical radiance values
Built-in Examples and Viewer
import less
less.examples.list() # list all built-in scenes
less.examples.run("autumn_forest") # launch interactive viewer
less.examples.run("maize_field")
scene.show() # open 3D viewer in browser (Scene / Simulate / Products tabs)
Validation
LESS 3.0 is cross-validated against the original LESS on reference scenes:
| Scene | Description | Max RRMSE |
|---|---|---|
| Val01 | Lambertian ground | 0.02% |
| Val02 | Box canopy | 0.22% |
| Val03 | Ellipsoid forest | 0.83% |
| Val04 | Forest + diffuse sky | 2.17% |
| Val05 | PROSPECT-D leaves | 0.24% |
| Val06 | fPAR vs sun zenith angle | 0.62% |
| Val07 | Thermal IR | 0.17% |
Full validation reports are regenerated on each release. See tests/validation/.
Backend LiDAR throughput and CPU/GPU crossover can be reproduced with:
python benchmarks/benchmark_lidar_scaling.py
The benchmark reports fast point-cloud and full-waveform throughput at 1 thousand through 1 million pulses and checks numerical agreement against the Embree backend.
Documentation and Tutorials
Full documentation with step-by-step tutorials:
Topics covered: coordinate system · terrain and surface properties · illumination models · optical imaging · BRDF/BRF sampling · thermal infrared · LiDAR · energy balance · photosynthesis · SIF · visualization · scene serialization
Citing
If you use LESS 3.0 in your research, please cite the original LESS paper:
Qi, J., Xie, D., Yin, T., Yan, G., Gastellu-Etchegorry, J.P., Li, L., Zhang, W., Mu, X., Norford, L.K. (2019). LESS: LargE-Scale remote sensing data and image Simulation framework over heterogeneous 3D scenes. Remote Sensing of Environment, 221, 695–706.
Metadata
Release files for less3d 0.4.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| less3d-0.4.3-cp313-cp313-win_amd64.whl | CPython 3.13 | CPython 3.13 | Windows x86-64 | Details |
| less3d-0.4.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.13 | CPython 3.13 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| less3d-0.4.3-cp312-cp312-win_amd64.whl | CPython 3.12 | CPython 3.12 | Windows x86-64 | Details |
| less3d-0.4.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| less3d-0.4.3-cp311-cp311-win_amd64.whl | CPython 3.11 | CPython 3.11 | Windows x86-64 | Details |
| less3d-0.4.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.28+ x86-64, Linux glibc 2.27+ x86-64 | Details |
| less3d-0.4.3-cp310-cp310-win_amd64.whl | CPython 3.10 | CPython 3.10 | Windows x86-64 | Details |
| less3d-0.4.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.10 | CPython 3.10 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
Total release size: 345.9 MB
Release files / less3d-0.4.3-cp313-cp313-win_amd64.whl
| Download URL | less3d-0.4.3-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 28.1 MB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
36c0025e98da671ae059757b2f1f5e119096f070cbe7dc11e3aaf7159889fbb6
|
|
BLAKE2b-256 checksum How to use checksums |
7d6115c275f9d64255c711e34d14dd36cae581310f71b6dfe47e2e63cf794a74
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / less3d-0.4.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | less3d-0.4.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 58.4 MB |
| Tags | CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
c60f0ae761cd5447acbcae23c9ea511405e5348b799547ac30dd81f58cdbf7c5
|
|
BLAKE2b-256 checksum How to use checksums |
7c48df65e26f7e2b88d3509c5eb2f7d4be1afd2fbebed2b04ba730a262779511
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / less3d-0.4.3-cp312-cp312-win_amd64.whl
| Download URL | less3d-0.4.3-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 28.1 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
f9a4ff3e4b761be6336f1d5de09db2b86fa11b82ad2632d5b342d0c97627c877
|
|
BLAKE2b-256 checksum How to use checksums |
9190ce9034a71de3dc081386cbf0db6f65d46bce28e83406de1bdc96556460b9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / less3d-0.4.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | less3d-0.4.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 58.4 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
81c8081f46ffd1d0dff1a20b3bb49c209e3322bf05dd864e4f56e260f2a99d62
|
|
BLAKE2b-256 checksum How to use checksums |
46ca00a13e0f7fa7c5da0a086d65d73be21982b1e673156a758039088e9d3da3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / less3d-0.4.3-cp311-cp311-win_amd64.whl
| Download URL | less3d-0.4.3-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 28.1 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
a54f6ff2832c055118d96f0fce07eb9c14bce053c87c2373f4a0b09178e93c22
|
|
BLAKE2b-256 checksum How to use checksums |
ed68d1b1d128c23f724fd748d1be1021e435266bd191b16aa41a2c56608caf58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / less3d-0.4.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | less3d-0.4.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 58.4 MB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
779c664508ee18fcc475222d133d106c09308b23857f9138748924f96b7cc67a
|
|
BLAKE2b-256 checksum How to use checksums |
251815f26681278b39708e0e6c357311ddce028c3f22edf23618e19932567896
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / less3d-0.4.3-cp310-cp310-win_amd64.whl
| Download URL | less3d-0.4.3-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 28.1 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
4c8a31f41afcb04eeb0dda9807b87510d56eeb0a7944d5415463dc8f575db290
|
|
BLAKE2b-256 checksum How to use checksums |
2f05f811c30603436bba3bd2ac50e8a9b130ab4a1b3c86ccf25d8586ab1055a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / less3d-0.4.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | less3d-0.4.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 58.4 MB |
| Tags | CPython 3.10 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
558633b1bc65e26d842ed84753fe4d8d076fcee19fb2e676e343bafdc59b1d1d
|
|
BLAKE2b-256 checksum How to use checksums |
20cbdfb7fda26c7272b7ba8eef3965f3ef9be399fb953398ace9014903563dea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|