08b - Statistical vegetation (TurbidBoundary)¶
When the number of leaves in the scene is very large, TurbidBoundary can be used to describe the space occupied by the canopy, and leaf area density, leaf inclination angle distribution, and leaf optical properties can be used to describe the internal leaves. It is suitable for large-scale forests, crop groups, and scenarios that require simultaneous calculation of optical, thermal infrared, and physiological processes.
When to use statistical vegetation¶
| Expression | Applicable scenarios |
|---|---|
Mesh |
Requires explicit leaf shape, veins or local geometric details |
TurbidBoundary |
The number of leaves is large, focusing on canopy-scale radiation and physiological quantities |
| Mesh + TurbidBoundary | Mesh is used for trunks and branches, and statistical vegetation is used for leaf clusters |
The boundary grid only specifies the spatial extent of the medium. It is the statistical leaves inside the boundary that are really involved in the calculations of scattering, absorption, thermal emission and physiology.
Prepare to close the border¶
The boundary OBJ must satisfy:
- Triangular surfaces form a closed, non-self-intersecting volume;
- The faces are facing the same direction;
- No openings, repeating faces or zero-area triangles;
- Still within the valid scene range after placement and scaling.
import less
crown = less.TurbidBoundary(
less.examples.asset_path("mixed_canopy.obj"),
group="crown",
sampling=less.TurbidSampling(
quality="standard",
seed=7,
),
)
Set internal blades¶
leaf = less.Fluspect(
cab=40,
car=10,
cw=0.012,
cm=0.009,
fqe=0.012,
)
vegetation = less.OpticalVegetation(
leaf=leaf,
leaf_area_density=1.25,
leaf_angle_distribution="spherical",
leaf_size=(0.08, 0.04),
leaf_shape="ellipse",
)
The unit of leaf_area_density is m² leaf area / m³ canopy volume. Commonly used leaf inclination angle distribution is:
| Name | Blade direction characteristics |
|---|---|
spherical |
Spherical distribution, often used in canopies that lack measured information |
uniform |
Uniform inclination angle |
planophile |
More horizontal leaves |
erectophile |
More upright leaves |
plagiophile |
More medium-inclined leaves |
extremophile |
More horizontal and upright leaves |
Build a hybrid Mesh / Turbid scene¶
plant = less.Object("mixed_plant")
plant.add_component("crown", crown)
plant.add_component(
"stem",
less.Mesh(less.examples.asset_path("mixed_canopy.obj"), group="stem"),
)
plant.set_property("crown", vegetation)
plant.set_property("stem", less.Lambertian(reflectance=0.10))
scene = less.Scene(backend="optix")
scene.size = (20.0, 20.0)
scene.terrain = less.Terrain(property=less.Lambertian(reflectance=0.15))
scene.illumination = less.Illumination(source=less.Sun(zenith=30, azimuth=150), atmosphere=less.SimpleSpectralAtmosphere(turbidity=2.5))
scene.add(plant, positions=[(5, 5, 0), (10, 10, 0), (15, 15, 0)])
The same light path will handle explicit mesh surfaces, statistical leaves, terrain, and multiple scattering, so there is no need to simulate them separately and then superimpose them.
Optical imaging¶
image = scene.simulate(
less.OpticalImager(
projection=less.Orthographic(image_size=256),
bands=[550, 680, 850],
quality=64,
),
scattering_order=8,
)
image.to_brf().save("turbid_brf.tif")
The resulting band order is consistent with bands. Radiance products can be converted to BRF using to_brf().
LAI and leaf area¶
The leaf area of statistical vegetation is determined by the boundary effective volume and leaf_area_density. Scaling the boundary changes the volume and therefore the total leaf area.
Energy balance and leaf temperature¶
Add thermal, biophysical, and stomatal conductance models to the canopy:
plant.set_property(
"crown",
less.ThermalProperty(emissivity=0.98, temperature="air"),
)
plant.set_property(
"crown",
less.BiophysicalProperty(
leaf_width=0.04,
stomatal_resistance=100.0,
stomata_side="bottom",
),
)
microclimate = less.Microclimate(
air_temperature=27.0,
humidity=60.0,
wind_speed=2.0,
)
energy = scene.simulate(
less.EnergyBalanceProcess(quality="standard"),
microclimate=microclimate,
)
The results preserve both sun and shade leaf condition temperatures and provide leaf temperature and energy closure information aggregated by component.
Photosynthesis¶
plant.set_property(
"crown",
less.Farquhar(Vcmax25=60.0, Jmax25=120.0),
)
photo = scene.simulate(
less.PhotosynthesisProcess(
temperature_mode="dynamic",
quality="standard",
),
microclimate=microclimate,
)
for key, apar, assimilation in zip(
photo.component_keys, photo.APAR, photo.An
):
print(key, apar, assimilation)
The unit of APAR is µmol photons m^-2 leaf s^-1, and the unit of An is µmol CO2 m^-2 leaf s^-1. The dynamic temperature model jointly solves for leaf temperature, stomatal conductance, and net photosynthetic rate.
SIF Source term and imaging¶
sif_source = scene.simulate(
less.SIFProcess(mode="dynamic", photo=photo)
)
sif_image = scene.simulate(less.SIFImager(
projection=less.Orthographic(image_size=256),
bands=[687, 740, 760],
quality=128,
sif_result=sif_source,
))
sif_image.save("turbid_sif.tif")
SIF The image unit is W m^-2 sr^-1 nm^-1. mode="dynamic" uses photosynthetic results; mode="static" uses leaf fluorescence quantum yield.
Thermal infrared imaging¶
thermal = scene.simulate(less.ThermalImager(
projection=less.Orthographic(image_size=256),
bands=[10600],
quality=64,
mode="precomputed",
eb_result=energy,
))
thermal.save("turbid_thermal.tif")
mode="precomputed" Sun and shade leaf temperatures obtained using energy balance. If you only set the fixed ThermalProperty, you can use the default mode="auto".
Sampling accuracy¶
TurbidSampling controls the accuracy of statistical blade pools and spatial fields:
sampling = less.TurbidSampling(
quality="high",
sample_budget=16384,
seed=42,
orientation_theta_bins=4,
orientation_phi_bins=8,
max_samples_per_leaf_cell=64,
)
| Parameters | Function |
|---|---|
quality |
Preset sampling quality; optional preview, standard, high |
sample_budget |
Target number of samples per placement instance; determined by quality preset when omitted |
seed |
Seed of repeatable random sequence |
orientation_theta_bins / orientation_phi_bins |
Discrete number of blade direction |
max_samples_per_leaf_cell |
Sample upper limit of adaptive spatial unit |
Use preview to check the scene and parameters first, then use standard or high to generate official results. Identical seeds and configurations keep sample prefixes stable, making it easier to compare different quality settings.
Save and reuse¶
TurbidSampling will be serialized with Scene/Project. There is no need to rebuild the geometry when only lighting, optical properties, or microclimate are modified; after modifying boundaries, instance positions, leaf area density, leaf inclination, or sample seeds, the statistical leaf field is updated on the next build.
See scripts/08b_turbid_medium.py for a complete example.
Related API¶
less.TurbidBoundary、less.TurbidSamplingless.OpticalVegetation、less.Fluspect、less.Lambertianless.Mesh、less.Object、less.Scene、less.Terrainless.LAIMeasurement、less.OpticalImager、less.BRFSensorless.ThermalProperty、less.BiophysicalProperty、less.Farquharless.Microclimate、less.EnergyBalanceProcess、less.PhotosynthesisProcessless.SIFProcess、less.SIFImager、less.ThermalImager
The next chapter covers multispectral and hyperspectral simulations.