SILVO is a lightweight 3D ray-tracing model for vegetation canopy structure, light interception, gap fraction, and illumination. It is designed for heterogeneous canopies such as orchards, open woodlands, agroforestry systems, and isolated trees using minimal inputs: tree crown position/size plus sun/view geometry.
Keywords: vegetation canopy model, light interception model, gap fraction, tree crown geometry, orchard simulation, agroforestry model, ray tracing.
It is designed to be fast and reproducible, and it is parallelised with OpenMP.
- Gap fraction and sunlit/shaded fractions (soil & vegetation)
- Vertical structural proxies (density / profiles) that can constrain 1D RTMs (e.g., SAIL/SCOPE-type workflows)
- A quick-look render (PPM) and analysis-ready rasters (ENVI BIP + HDR)
sudo apt update
sudo apt install -y build-essentialgit clone https://github.com/ahornero/silvo.git
cd silvoFrom the repository root:
makeThe executable is created at (already precompiled in the repo for amd64)
./bin/silvocd examples/ourique_default
./run_silvo.shOutputs are written in the folder where you run SILVO (e.g., inside the example directory) and from the previous example should generate a BIL (ENVI) file (with its header, hdr companion file) containing all the output as layers and a PNG image as preview.
By default, SILVO reads the following files from the current working directory:
- scene.txt
- settings.txt
But they can be chosen from the command line as arguments:
./bin/silvo --scene path/to/scene.txt --config path/to/settings.txtSame applies for the solar and camera settings. Command-line values take precedence over settings.txt:
./bin/silvo --scene scene.txt --config settings.txt \
--sza 35 --saa 120 --cza 0 --caa 0 --cds 600 --fov 30./bin/silvo -h
Usage: ./bin/silvo
[-s|--scene scene_file (scene.txt)]
[-c|--config config_file (settings.txt)]
[--sza value] [--saa value] [--cza value] [--caa value] [--cds value] [--fov value]
[-h] (show this)Plain text. Each non-comment (#...) line contains:
x y z radius
- Lines starting with # are ignored.
- z is typically 0 for flat terrain (SILVO places spheres sitting on the ground). Example:
# x y z radius
0.0 0.0 0.0 2.5
8.0 0.0 0.0 2.0
0.0 8.0 0.0 3.0
Plain text key/value pairs, e.g.:
solar_zenith = 35
solar_azimuth = 120
camera_zenith = 0
camera_azimuth = 0
camera_distance = 600
camera_fov = 30
debug = 0
gap_fraction_profile_enabled = 0
SILVO writes outputs to the current working directory:
- output_image.ppm — RGB quick-look render
- output.bip + output.hdr — ENVI BIP (15 bands, float32) + header
- Console metrics (stdout): gap fraction, sunlit/shaded fractions, normalised density
- Optional CSV profiles:
- vertical_profile.csv (generated when camera_zenith == 90)
- gap_fraction_profile.csv (generated when gap_fraction_profile_enabled = 1 and camera_zenith != 90)
If you use SILVO in academic work, please cite:
Hornero, A., Prikaziuk, E., Hernandez-Clemente, R., van der Tol, C. (2026).
SILVO, a lightweight 3D illumination model to characterise the spatial structure of heterogeneous vegetation canopies.
International Journal of Applied Earth Observation and Geoinformation, 147, 105178. https://doi.org/10.1016/j.jag.2026.105178
@article{Hornero2026SILVO,
title = {SILVO, a lightweight 3D illumination model to characterise the spatial structure of heterogeneous vegetation canopies},
author = {Hornero, A. and Prikaziuk, E. and Hernandez-Clemente, R. and van der Tol, C.},
journal = {International Journal of Applied Earth Observation and Geoinformation},
volume = {147},
pages = {105178},
year = {2026},
issn = {1569-8432},
doi = {10.1016/j.jag.2026.105178},
url = {https://doi.org/10.1016/j.jag.2026.105178}
}